TestSearchPaths.java revision 3294:9adfb22ff08f
11541Srgrimes/* 21541Srgrimes * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. 31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41541Srgrimes * 51541Srgrimes * This code is free software; you can redistribute it and/or modify it 61541Srgrimes * under the terms of the GNU General Public License version 2 only, as 71541Srgrimes * published by the Free Software Foundation. 81541Srgrimes * 91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 131541Srgrimes * accompanied this code). 141541Srgrimes * 151541Srgrimes * You should have received a copy of the GNU General Public License version 161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 181541Srgrimes * 191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 201541Srgrimes * or visit www.oracle.com if you need additional information or have any 211541Srgrimes * questions. 221541Srgrimes */ 231541Srgrimes 241541Srgrimes/* 251541Srgrimes * @test 261541Srgrimes * @bug 7026941 271541Srgrimes * @summary path options ignored when reusing filemanager across tasks 281541Srgrimes * @modules java.compiler 291541Srgrimes * jdk.compiler 301541Srgrimes */ 311541Srgrimes 321541Srgrimesimport java.io.File; 3314505Shsuimport java.io.FileWriter; 3450477Speterimport java.io.IOException; 351541Srgrimesimport java.io.PrintWriter; 361541Srgrimesimport java.net.URI; 372165Spaulimport java.nio.file.Files; 382165Spaulimport java.util.ArrayList; 392165Spaulimport java.util.Arrays; 4015492Sbdeimport java.util.Collections; 411541Srgrimesimport java.util.EnumSet; 421541Srgrimesimport java.util.List; 431541Srgrimesimport java.util.Objects; 441541Srgrimesimport java.util.jar.JarEntry; 451541Srgrimesimport java.util.jar.JarOutputStream; 461541Srgrimesimport java.util.regex.Matcher; 471541Srgrimesimport java.util.regex.Pattern; 481541Srgrimes 4936079Swollmanimport javax.tools.JavaCompiler; 5036079Swollmanimport javax.tools.JavaCompiler.CompilationTask; 511541Srgrimesimport javax.tools.JavaFileObject; 5236079Swollmanimport javax.tools.SimpleJavaFileObject; 531541Srgrimesimport javax.tools.StandardJavaFileManager; 541541Srgrimesimport javax.tools.StandardLocation; 551541Srgrimesimport javax.tools.ToolProvider; 561541Srgrimes 571541Srgrimesimport static javax.tools.StandardLocation.*; 581541Srgrimes 591541Srgrimes/** 6013765Smpp * Test for combinations of using javac command-line options and fileManager setLocation 611541Srgrimes * calls to affect the locations available in the fileManager. 621541Srgrimes * 631541Srgrimes * Using a single Java compiler and file manager, for each of the standard locations, 641541Srgrimes * a series of operations is performed, using either compiler options or setLocation 651541Srgrimes * calls. Each operation includes a compilation, and then a check for the value of 661541Srgrimes * the standard location available in the file manager. 671541Srgrimes * 681541Srgrimes * The operations generate and use unique files to minimize the possibility of false 691541Srgrimes * positive results. 701541Srgrimes */ 7114547Sdgpublic class TestSearchPaths { 7214547Sdg 7314547Sdg public static void main(String... args) throws Exception { 7414547Sdg TestSearchPaths t = new TestSearchPaths(); 7518787Spst t.run(); 7618787Spst } 771541Srgrimes 781541Srgrimes void run() throws Exception { 791541Srgrimes compiler = ToolProvider.getSystemJavaCompiler(); 8041087Struckman fileManager = compiler.getStandardFileManager(null, null, null); 8141087Struckman try { 821541Srgrimes // basic output path 8355943Sjasone testClassOutput(); 841541Srgrimes 851541Srgrimes // basic search paths 861541Srgrimes testClassPath(); 871541Srgrimes testSourcePath(); 881541Srgrimes testPlatformClassPath(); 891541Srgrimes 901541Srgrimes // annotation processing 911541Srgrimes testAnnotationProcessorPath(); 921541Srgrimes testSourceOutput(); 931541Srgrimes 941541Srgrimes // javah equivalent 951541Srgrimes testNativeHeaderOutput(); 961541Srgrimes 971541Srgrimes // future-proof: guard against new StandardLocations being added 981541Srgrimes if (!tested.equals(EnumSet.allOf(StandardLocation.class))) { 991541Srgrimes // FIXME: need to update for JDK 9 locations 1001541Srgrimes // error("not all standard locations have been tested"); 1011541Srgrimes out.println("not yet tested: " + EnumSet.complementOf(tested)); 1021541Srgrimes } 1031541Srgrimes 10436527Speter if (errors > 0) { 1051541Srgrimes throw new Exception(errors + " errors occurred"); 10655943Sjasone } 1071541Srgrimes } finally { 10838482Swollman fileManager.close(); 10938482Swollman } 11051381Sgreen } 11138482Swollman 11236079Swollman void testClassOutput() throws IOException { 11343458Sbde String test = "testClassOutput"; 1141541Srgrimes System.err.println("test: " + test); 1151541Srgrimes 1161541Srgrimes for (int i = 1; i <= 5; i++) { 1171541Srgrimes File classes = createDir(test + "/" + i + "/classes"); 1181541Srgrimes List<String> options; 11914547Sdg switch (i) { 12014547Sdg default: 12114547Sdg options = getOptions("-d", classes.getPath()); 12214547Sdg break; 12314547Sdg 12414547Sdg case 3: 12514547Sdg setLocation(CLASS_OUTPUT, classes); 1261541Srgrimes options = null; 12714547Sdg break; 12814547Sdg } 12914547Sdg List<JavaFileObject> sources = getSources("class C" + i + " { }"); 1301541Srgrimes callTask(options, sources); 13114547Sdg checkPath(CLASS_OUTPUT, Mode.EQUALS, classes); 13214547Sdg checkFile(CLASS_OUTPUT, "C" + i + ".class"); 13343196Sfenner } 1341541Srgrimes 13536079Swollman tested.add(CLASS_OUTPUT); 13636079Swollman } 13736079Swollman 13836079Swollman void testClassPath() throws IOException { 13936079Swollman String test = "testClassPath"; 14036079Swollman System.err.println("test: " + test); 14136079Swollman 14236079Swollman for (int i = 1; i <= 5; i++) { 14336079Swollman File classes = createDir(test + "/" + i + "/classes"); 14436079Swollman File classpath = new File("testClassOutput/" + i + "/classes"); 14536079Swollman List<String> options; 14636079Swollman switch (i) { 14736079Swollman default: 14836079Swollman options = getOptions("-d", classes.getPath(), "-classpath", classpath.getPath()); 14936079Swollman break; 15036079Swollman 15136079Swollman case 3: 15236079Swollman setLocation(CLASS_PATH, classpath); 15336079Swollman options = getOptions("-d", classes.getPath()); 15436079Swollman break; 15536079Swollman 15636079Swollman case 4: 15736079Swollman options = getOptions("-d", classes.getPath(), "-cp", classpath.getPath()); 15836079Swollman break; 15936079Swollman } 16036079Swollman List<JavaFileObject> sources = getSources("class D" + i + " { C" + i + " c; }"); 16136079Swollman callTask(options, sources); 16236079Swollman checkPath(CLASS_PATH, Mode.EQUALS, classpath); 16336079Swollman checkFile(CLASS_OUTPUT, "D" + i + ".class"); 16436079Swollman } 16536079Swollman 16614547Sdg tested.add(CLASS_PATH); 1671541Srgrimes System.err.println(); 1681541Srgrimes } 1691541Srgrimes 1701541Srgrimes void testSourcePath() throws IOException { 1711541Srgrimes String test = "testSourcePath"; 17236527Speter System.err.println("test: " + test); 17336527Speter setLocation(CLASS_PATH); // empty 17455943Sjasone 17555943Sjasone for (int i = 1; i <= 5; i++) { 17636527Speter File src = createDir(test + "/" + i + "/src"); 17736527Speter writeFile(src, "C" + i + ".java", "class C" + i + "{ }"); 1781541Srgrimes File classes = createDir(test + "/" + i + "/classes"); 1791541Srgrimes File srcpath = src; 1801541Srgrimes List<String> options; 1811541Srgrimes switch (i) { 1821541Srgrimes default: 1831541Srgrimes options = getOptions("-d", classes.getPath(), "-sourcepath", srcpath.getPath()); 1841541Srgrimes break; 1851541Srgrimes 1861541Srgrimes case 3: 1871541Srgrimes setLocation(SOURCE_PATH, srcpath); 1881541Srgrimes options = getOptions("-d", classes.getPath()); 1891541Srgrimes break; 1901541Srgrimes } 1911541Srgrimes List<JavaFileObject> sources = getSources("class D" + i + " { C" + i + " c; }"); 1921541Srgrimes callTask(options, sources); 1931541Srgrimes checkPath(SOURCE_PATH, Mode.EQUALS, srcpath); 1941541Srgrimes checkFile(CLASS_OUTPUT, "D" + i + ".class"); 19514547Sdg } 1961541Srgrimes 1971541Srgrimes tested.add(SOURCE_PATH); 1981541Srgrimes System.err.println(); 1993304Sphk } 2001541Srgrimes 2013304Sphk void testPlatformClassPath() throws IOException { 2021541Srgrimes String test = "testPlatformClassPath"; 2031541Srgrimes System.err.println("test: " + test); 2041541Srgrimes 2051541Srgrimes List<File> defaultPath = getLocation(PLATFORM_CLASS_PATH); 2061541Srgrimes StringBuilder sb = new StringBuilder(); 2071541Srgrimes for (File f: defaultPath) { 2081541Srgrimes if (sb.length() > 0) 2091541Srgrimes sb.append(File.pathSeparator); 2101541Srgrimes sb.append(f); 2111541Srgrimes } 2121541Srgrimes String defaultPathString = sb.toString(); 2131541Srgrimes 2141541Srgrimes setLocation(CLASS_PATH); // empty 2151541Srgrimes setLocation(SOURCE_PATH); // empty 2161541Srgrimes 2171541Srgrimes // Use -source 8 -target 8 to enable use of platform class path options 2181541Srgrimes // FIXME: temporarily exclude cases referring to default bootclasspath 2191541Srgrimes // for (int i = 1; i <= 10; i++) { 2201541Srgrimes int[] cases = new int[] { 1, 2, 4, 5, 6, 7 }; 2211541Srgrimes for (int i : cases) { 2221541Srgrimes File classes = createDir(test + "/" + i + "/classes"); 2231541Srgrimes File testJars = createDir(test + "/" + i + "/testJars"); 2241541Srgrimes File testClasses = createDir(test + "/" + i + "/testClasses"); 2251541Srgrimes callTask(getOptions("-d", testClasses.getPath()), getSources("class C" + i + " { }")); 2261541Srgrimes 2271541Srgrimes List<String> options; 2281541Srgrimes Mode mode; 2291541Srgrimes List<File> match; 2301541Srgrimes String reference = "C" + i + " c;"; 2311541Srgrimes 2321541Srgrimes File jar; 2331541Srgrimes 2341541Srgrimes switch (i) { 2351541Srgrimes case 1: 2361541Srgrimes options = getOptions("-d", classes.getPath(), 2371541Srgrimes "-source", "8", "-target", "8", 2381541Srgrimes "-Xbootclasspath/p:" + testClasses); 23936527Speter mode = Mode.STARTS_WITH; 24036527Speter match = Arrays.asList(testClasses); 24136527Speter break; 24236527Speter 2431541Srgrimes case 2: 24436527Speter // the default values for -extdirs and -endorseddirs come after the bootclasspath; 24536527Speter // so to check -Xbootclasspath/a: we specify empty values for those options. 24636527Speter options = getOptions("-d", classes.getPath(), 24736527Speter "-source", "8", "-target", "8", 2481541Srgrimes "-Xbootclasspath/a:" + testClasses, 24955205Speter "-extdirs", "", 25031927Sbde "-endorseddirs", ""); 25138482Swollman mode = Mode.ENDS_WITH; 25238482Swollman match = Arrays.asList(testClasses); 25338482Swollman break; 25438482Swollman 25538482Swollman case 3: 25638482Swollman options = getOptions("-d", classes.getPath(), "-Xbootclasspath:" + defaultPathString); 25738482Swollman mode = Mode.EQUALS; 25838482Swollman match = defaultPath; 25938482Swollman reference = ""; 26038482Swollman break; 26138482Swollman 26238482Swollman case 4: 26338482Swollman fileManager.setLocation(PLATFORM_CLASS_PATH, null); 26438482Swollman jar = new File(testJars, "j" + i + ".jar"); 26540931Sdg writeJar(jar, testClasses, "C" + i + ".class"); 26640931Sdg options = getOptions("-d", classes.getPath(), 26740931Sdg "-source", "8", "-target", "8", 26840931Sdg "-endorseddirs", testJars.getPath()); 26940931Sdg mode = Mode.CONTAINS; 27040931Sdg match = Arrays.asList(jar); 27140931Sdg break; 27231927Sbde 27331927Sbde case 5: 27431927Sbde fileManager.setLocation(PLATFORM_CLASS_PATH, null); 27531927Sbde jar = new File(testJars, "j" + i + ".jar"); 27631927Sbde writeJar(jar, testClasses, "C" + i + ".class"); 27736079Swollman options = getOptions("-d", classes.getPath(), 2782112Swollman "-source", "8", "-target", "8", 27936079Swollman "-Djava.endorsed.dirs=" + testJars.getPath()); 28036079Swollman mode = Mode.CONTAINS; 28114505Shsu match = Arrays.asList(jar); 28232995Sbde break; 28315492Sbde 28415492Sbde case 6: 28515492Sbde fileManager.setLocation(PLATFORM_CLASS_PATH, null); 28615492Sbde jar = new File(testJars, "j" + i + ".jar"); 28732995Sbde writeJar(jar, testClasses, "C" + i + ".class"); 28832995Sbde options = getOptions("-d", classes.getPath(), 28915492Sbde "-source", "8", "-target", "8", 2901541Srgrimes "-extdirs", testJars.getPath()); 2911541Srgrimes mode = Mode.CONTAINS; 2921541Srgrimes match = Arrays.asList(jar); 29345311Sdt break; 29451418Sgreen 29545311Sdt case 7: 29651418Sgreen fileManager.setLocation(PLATFORM_CLASS_PATH, null); 29743512Snewton jar = new File(testJars, "j" + i + ".jar"); 29836735Sdfr writeJar(jar, testClasses, "C" + i + ".class"); 29914505Shsu options = getOptions("-d", classes.getPath(), 30029350Speter "-source", "8", "-target", "8", 30129350Speter "-Djava.ext.dirs=" + testJars.getPath()); 30252984Speter mode = Mode.CONTAINS; 3033304Sphk match = Arrays.asList(jar); 3043304Sphk break; 3053304Sphk 3063304Sphk case 8: 30728270Swollman setLocation(PLATFORM_CLASS_PATH, defaultPath); 30814505Shsu options = getOptions("-d", classes.getPath()); 30914505Shsu mode = Mode.EQUALS; 31028270Swollman match = defaultPath; 31114505Shsu reference = ""; 31214505Shsu break; 31314505Shsu 31414505Shsu default: 31514505Shsu options = getOptions("-d", classes.getPath(), 31614505Shsu "-source", "8", "-target", "8", 31714505Shsu "-bootclasspath", defaultPathString); 31814505Shsu mode = Mode.EQUALS; 31919670Sbde match = defaultPath; 32019670Sbde reference = ""; 32114505Shsu break; 32214505Shsu } 32314505Shsu List<JavaFileObject> sources = getSources("class D" + i + " { " + reference + " }"); 32414505Shsu 32552070Sgreen callTask(options, sources); 32652070Sgreen checkPath(PLATFORM_CLASS_PATH, mode, match); 32752070Sgreen checkFile(CLASS_OUTPUT, "D" + i + ".class"); 32836079Swollman } 32914505Shsu 33014505Shsu tested.add(PLATFORM_CLASS_PATH); 33114505Shsu System.err.println(); 33228270Swollman } 33336079Swollman 33428270Swollman void testAnnotationProcessorPath() throws IOException { 33514505Shsu String test = "testAnnotationProcessorPath"; 33614505Shsu System.err.println("test: " + test); 33714505Shsu 33828270Swollman fileManager.setLocation(PLATFORM_CLASS_PATH, null); 33914505Shsu 34014505Shsu String template = 34114505Shsu "import java.util.*;\n" 34236079Swollman + "import javax.annotation.processing.*;\n" 34314505Shsu + "import javax.lang.model.*;\n" 34414505Shsu + "import javax.lang.model.element.*;\n" 34538482Swollman + "@SupportedAnnotationTypes(\"*\")\n" 34614505Shsu + "public class A%d extends AbstractProcessor {\n" 34714505Shsu + " public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) {\n" 34814505Shsu + " return true;\n" 34914505Shsu + " }\n" 35014505Shsu + " public SourceVersion getSupportedSourceVersion() {\n" 35125201Swollman + " return SourceVersion.latest();\n" 35214505Shsu + " }\n" 35318787Spst + "}"; 35418787Spst 35527531Sfenner for (int i = 1; i <= 5; i++) { 35651381Sgreen File classes = createDir(test + "/" + i + "/classes"); 35751381Sgreen File annodir = createDir(test + "/" + i + "/processors"); 35838482Swollman callTask(getOptions("-d", annodir.getPath()), getSources(String.format(template, i))); 35938482Swollman File annopath = annodir; 36038482Swollman List<String> options; 36153541Sshin switch (i) { 36253541Sshin default: 36353541Sshin options = getOptions("-d", classes.getPath(), 36453541Sshin "-processorpath", annopath.getPath(), 36553541Sshin "-processor", "A" + i); 36653541Sshin break; 36729350Speter 36829350Speter case 3: 36928270Swollman setLocation(ANNOTATION_PROCESSOR_PATH, annopath); 37028270Swollman options = getOptions("-d", classes.getPath(), 37128270Swollman "-processor", "A" + i); 37214505Shsu break; 37314505Shsu } 37428270Swollman List<JavaFileObject> sources = getSources("class D" + i + " { }"); 37528270Swollman callTask(options, sources); 37628270Swollman checkPath(ANNOTATION_PROCESSOR_PATH, Mode.EQUALS, annopath); 37738482Swollman checkFile(CLASS_OUTPUT, "D" + i + ".class"); 37814505Shsu } 37936079Swollman 38014505Shsu tested.add(ANNOTATION_PROCESSOR_PATH); 38131927Sbde System.err.println(); 38255205Speter } 3832165Spaul 38414505Shsu void testSourceOutput() throws IOException { 385 String test = "testAnnotationProcessorPath"; 386 System.err.println("test: " + test); 387 388 String source = 389 "import java.io.*;\n" 390 + "import java.util.*;\n" 391 + "import javax.annotation.processing.*;\n" 392 + "import javax.lang.model.*;\n" 393 + "import javax.lang.model.element.*;\n" 394 + "import javax.tools.*;\n" 395 + "@SupportedOptions(\"name\")\n" 396 + "@SupportedAnnotationTypes(\"*\")\n" 397 + "public class A extends AbstractProcessor {\n" 398 + " int round = 0;\n" 399 + " public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) {\n" 400 + " if (round++ == 0) try {\n" 401 + " String name = processingEnv.getOptions().get(\"name\");\n" 402 + " JavaFileObject fo = processingEnv.getFiler().createSourceFile(name);\n" 403 + " try (Writer out = fo.openWriter()) {\n" 404 + " out.write(\"class \" + name + \" { }\");\n" 405 + " }\n" 406 + " } catch (IOException e) { throw new Error(e); }\n" 407 + " return true;\n" 408 + " }\n" 409 + " public SourceVersion getSupportedSourceVersion() {\n" 410 + " return SourceVersion.latest();\n" 411 + " }\n" 412 + "}"; 413 414 File annodir = createDir(test + "/processors"); 415 callTask(getOptions("-d", annodir.getPath()), getSources(source)); 416 setLocation(ANNOTATION_PROCESSOR_PATH, annodir); 417 418 for (int i = 1; i <= 5; i++) { 419 File classes = createDir(test + "/" + i + "/classes"); 420 File genSrc = createDir(test + "/" + "/genSrc"); 421 List<String> options; 422 switch (i) { 423 default: 424 options = getOptions("-d", classes.getPath(), 425 "-processor", "A", "-Aname=G" + i, 426 "-s", genSrc.getPath()); 427 break; 428 429 case 3: 430 setLocation(SOURCE_OUTPUT, genSrc); 431 options = getOptions("-d", classes.getPath(), 432 "-processor", "A", "-Aname=G" + i); 433 break; 434 } 435 List<JavaFileObject> sources = getSources("class D" + i + " { }"); 436 callTask(options, sources); 437 checkPath(SOURCE_OUTPUT, Mode.EQUALS, genSrc); 438 checkFile(CLASS_OUTPUT, "D" + i + ".class"); 439 checkFile(CLASS_OUTPUT, "G" + i + ".class"); 440 } 441 tested.add(SOURCE_OUTPUT); 442 System.err.println(); 443 } 444 445 void testNativeHeaderOutput() throws IOException { 446 String test = "testNativeHeaderOutput"; 447 System.err.println("test: " + test); 448 449 for (int i = 1; i <= 5; i++) { 450 File classes = createDir(test + "/" + i + "/classes"); 451 File headers = createDir(test + "/" + i + "/hdrs"); 452 List<String> options; 453 switch (i) { 454 default: 455 options = getOptions("-d", classes.getPath(), "-h", headers.getPath()); 456 break; 457 458 case 3: 459 setLocation(NATIVE_HEADER_OUTPUT, headers); 460 options = getOptions("-d", classes.getPath()); 461 break; 462 } 463 List<JavaFileObject> sources = getSources("class C" + i + " { native void m(); }"); 464 callTask(options, sources); 465 checkPath(NATIVE_HEADER_OUTPUT, Mode.EQUALS, headers); 466 checkFile(NATIVE_HEADER_OUTPUT, "C" + i + ".h"); 467 } 468 469 tested.add(StandardLocation.NATIVE_HEADER_OUTPUT); 470 System.err.println(); 471 } 472 473 List<String> getOptions(String... args) { 474 return Arrays.asList(args); 475 } 476 477 List<JavaFileObject> getSources(String... sources) { 478 List<JavaFileObject> list = new ArrayList<>(); 479 for (String s: sources) 480 list.add(getSource(s)); 481 return list; 482 } 483 484 JavaFileObject getSource(final String source) { 485 return new SimpleJavaFileObject(getURIFromSource(source), JavaFileObject.Kind.SOURCE) { 486 @Override 487 public CharSequence getCharContent(boolean ignoreEncodingErrors) { 488 return source; 489 } 490 }; 491 } 492 493 void callTask(List<String> options, List<JavaFileObject> files) { 494 out.print("compile: "); 495 if (options != null) { 496 for (String o: options) { 497 if (o.length() > 64) { 498 o = o.substring(0, 32) + "..." + o.substring(o.length() - 32); 499 } 500 out.print(" " + o); 501 } 502 } 503 for (JavaFileObject f: files) 504 out.print(" " + f.getName()); 505 out.println(); 506 CompilationTask t = compiler.getTask(out, fileManager, null, options, null, files); 507 boolean ok = t.call(); 508 if (!ok) 509 error("compilation failed"); 510 } 511 512 enum Mode { EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH }; 513 514 void checkFile(StandardLocation l, String path) { 515 if (!l.isOutputLocation()) { 516 error("Not an output location: " + l); 517 return; 518 } 519 520 List<File> files = getLocation(l); 521 if (files == null) { 522 error("location is unset: " + l); 523 return; 524 } 525 526 if (files.size() != 1) 527 error("unexpected number of entries on " + l + ": " + files.size()); 528 529 File f = new File(files.get(0), path); 530 if (!f.exists()) 531 error("file not found: " + f); 532 } 533 534 void checkPath(StandardLocation l, Mode m, File expect) { 535 checkPath(l, m, Arrays.asList(expect)); 536 } 537 538 void checkPath(StandardLocation l, Mode m, List<File> expect) { 539 List<File> files = getLocation(l); 540 if (files == null) { 541 error("location is unset: " + l); 542 return; 543 } 544 545 switch (m) { 546 case EQUALS: 547 if (!Objects.equals(files, expect)) { 548 error("location does not match the expected files: " + l); 549 out.println("found: " + files); 550 out.println("expect: " + expect); 551 } 552 break; 553 554 case CONTAINS: 555 int containsIndex = Collections.indexOfSubList(files, expect); 556 if (containsIndex == -1) { 557 error("location does not contain the expected files: " + l); 558 out.println("found: " + files); 559 out.println("expect: " + expect); 560 } 561 break; 562 563 case STARTS_WITH: 564 int startsIndex = Collections.indexOfSubList(files, expect); 565 if (startsIndex != 0) { 566 error("location does not start with the expected files: " + l); 567 out.println("found: " + files); 568 out.println("expect: " + expect); 569 } 570 break; 571 572 case ENDS_WITH: 573 int endsIndex = Collections.lastIndexOfSubList(files, expect); 574 if (endsIndex != files.size() - expect.size()) { 575 error("location does not end with the expected files: " + l); 576 out.println("found: " + files); 577 out.println("expect: " + expect); 578 } 579 break; 580 581 } 582 } 583 584 List<File> getLocation(StandardLocation l) { 585 Iterable<? extends File> iter = fileManager.getLocation(l); 586 if (iter == null) 587 return null; 588 List<File> files = new ArrayList<>(); 589 for (File f: iter) 590 files.add(f); 591 return files; 592 } 593 594 void setLocation(StandardLocation l, File... files) throws IOException { 595 fileManager.setLocation(l, Arrays.asList(files)); 596 } 597 598 void setLocation(StandardLocation l, List<File> files) throws IOException { 599 fileManager.setLocation(l, files); 600 } 601 602 void writeFile(File dir, String path, String body) throws IOException { 603 try (FileWriter w = new FileWriter(new File(dir, path))) { 604 w.write(body); 605 } 606 } 607 608 void writeJar(File jar, File dir, String... entries) throws IOException { 609 try (JarOutputStream j = new JarOutputStream(Files.newOutputStream(jar.toPath()))) { 610 for (String entry: entries) { 611 j.putNextEntry(new JarEntry(entry)); 612 j.write(Files.readAllBytes(dir.toPath().resolve(entry))); 613 } 614 } 615 } 616 617 private static final Pattern packagePattern 618 = Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))"); 619 private static final Pattern classPattern 620 = Pattern.compile("(?:public\\s+)?(?:class|enum|interface)\\s+(\\w+)"); 621 622 623 private static URI getURIFromSource(String source) { 624 String packageName = null; 625 626 Matcher matcher = packagePattern.matcher(source); 627 if (matcher.find()) { 628 packageName = matcher.group(1).replace(".", "/"); 629 } 630 631 matcher = classPattern.matcher(source); 632 if (matcher.find()) { 633 String className = matcher.group(1); 634 String path = ((packageName == null) ? "" : packageName + "/") + className + ".java"; 635 return URI.create("myfo:///" + path); 636 } else { 637 throw new Error("Could not extract the java class " 638 + "name from the provided source"); 639 } 640 } 641 642 File createDir(String path) { 643 File dir = new File(path); 644 dir.mkdirs(); 645 return dir; 646 } 647 648 JavaCompiler compiler; 649 StandardJavaFileManager fileManager; 650 651 /** 652 * Map for recording which standard locations have been tested. 653 */ 654 EnumSet<StandardLocation> tested = EnumSet.noneOf(StandardLocation.class); 655 656 /** 657 * Logging stream. Used directly with test and for getTask calls. 658 */ 659 final PrintWriter out = new PrintWriter(System.err, true); 660 661 /** 662 * Count of errors so far. 663 */ 664 int errors; 665 666 void error(String message) { 667 errors++; 668 out.println("Error: " + message); 669 } 670} 671