1/* 2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/** 25 * @test 26 * @bug 8171005 8175560 27 * @summary Verify behavior of JavaFileManager methods w.r.t. module/package oriented locations 28 * @library /tools/lib 29 * @modules java.compiler 30 * @build toolbox.TestRunner ModuleAndPackageLocations 31 * @run main ModuleAndPackageLocations 32 */ 33 34import java.io.File; 35import java.io.IOException; 36import java.nio.file.Files; 37import java.nio.file.Path; 38import java.nio.file.Paths; 39import java.util.Arrays; 40import java.util.EnumSet; 41import java.util.HashSet; 42import java.util.List; 43import java.util.Objects; 44import java.util.Set; 45import java.util.concurrent.Callable; 46import java.util.stream.Collectors; 47import java.util.stream.StreamSupport; 48 49import javax.tools.JavaCompiler; 50import javax.tools.JavaFileManager; 51import javax.tools.JavaFileManager.Location; 52import javax.tools.JavaFileObject; 53import javax.tools.JavaFileObject.Kind; 54import javax.tools.StandardJavaFileManager; 55import javax.tools.StandardLocation; 56import javax.tools.ToolProvider; 57 58import toolbox.TestRunner; 59import toolbox.TestRunner.Test; 60 61public class ModuleAndPackageLocations extends TestRunner { 62 63 public static void main(String... args) throws Exception { 64 new ModuleAndPackageLocations().runTests(m -> new Object[] { Paths.get(m.getName()) }); 65 } 66 67 public ModuleAndPackageLocations() { 68 super(System.err); 69 } 70 71 @Test 72 public void testListLocations(Path outerBase) throws Exception { 73 doRunTest(outerBase, (base, fm) -> { 74 assertLocations(fm.listLocationsForModules(StandardLocation.MODULE_SOURCE_PATH), 75 toSet("MODULE_SOURCE_PATH[a]:false:false", 76 "MODULE_SOURCE_PATH[b]:false:false", 77 "MODULE_SOURCE_PATH[c]:false:false")); 78 assertLocations(fm.listLocationsForModules(StandardLocation.MODULE_PATH), 79 toSet("MODULE_PATH[0.X,a]:false:false", 80 "MODULE_PATH[0.X,b]:false:false"), 81 toSet("MODULE_PATH[1.X,c]:false:false", 82 "MODULE_PATH[1.X,b]:false:false")); 83 assertLocations(fm.listLocationsForModules(StandardLocation.SOURCE_OUTPUT), 84 toSet("SOURCE_OUTPUT[a]:false:true", 85 "SOURCE_OUTPUT[b]:false:true")); 86 87 fm.getLocationForModule(StandardLocation.SOURCE_OUTPUT, "c"); 88 89 assertLocations(fm.listLocationsForModules(StandardLocation.SOURCE_OUTPUT), 90 toSet("SOURCE_OUTPUT[a]:false:true", 91 "SOURCE_OUTPUT[b]:false:true", 92 "SOURCE_OUTPUT[c]:false:true")); 93 }); 94 } 95 96 @Test 97 public void testGetModuleForPath(Path outerBase) throws Exception { 98 doRunTest(outerBase, (base, fm) -> { 99 Location cOutput = fm.getLocationForModule(StandardLocation.SOURCE_OUTPUT, "c"); 100 JavaFileObject testFO = fm.getJavaFileForOutput(cOutput, "test.Test", Kind.CLASS, null); 101 testFO.openOutputStream().close(); 102 Location cOutput2 = fm.getLocationForModule(StandardLocation.SOURCE_OUTPUT, testFO); 103 104 if (cOutput != cOutput2) { 105 throw new AssertionError("Unexpected location: " + cOutput2 + ", expected: " +cOutput); 106 } 107 }); 108 } 109 110 @Test 111 public void testRejects(Path outerBase) throws Exception { 112 doRunTest(outerBase, (base, fm) -> { 113 assertRefused(() -> fm.getClassLoader(StandardLocation.MODULE_SOURCE_PATH)); 114 assertRefused(() -> fm.getFileForInput(StandardLocation.MODULE_SOURCE_PATH, "", "")); 115 assertRefused(() -> fm.getFileForOutput(StandardLocation.MODULE_SOURCE_PATH, "", "", null)); 116 assertRefused(() -> fm.getJavaFileForInput(StandardLocation.MODULE_SOURCE_PATH, "", Kind.SOURCE)); 117 assertRefused(() -> fm.getJavaFileForOutput(StandardLocation.MODULE_SOURCE_PATH, "", Kind.SOURCE, null)); 118 assertRefused(() -> fm.getLocationForModule(StandardLocation.SOURCE_PATH, "test")); 119 JavaFileObject out = fm.getJavaFileForInput(StandardLocation.CLASS_OUTPUT, "test.Test", Kind.CLASS); 120 assertRefused(() -> fm.inferBinaryName(StandardLocation.MODULE_PATH, out)); 121 assertRefused(() -> fm.inferModuleName(StandardLocation.MODULE_SOURCE_PATH)); 122 assertRefused(() -> fm.list(StandardLocation.MODULE_SOURCE_PATH, "test", EnumSet.allOf(Kind.class), false)); 123 assertRefused(() -> fm.listLocationsForModules(StandardLocation.SOURCE_PATH)); 124 }); 125 } 126 127 void doRunTest(Path base, TestExec test) throws Exception { 128 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 129 Path msp = base.resolve("msp"); 130 Path msp1 = msp.resolve("1"); 131 Path msp2 = msp.resolve("2"); 132 133 touch(msp1.resolve("a/module-info.java")); 134 Files.createDirectories(msp1.resolve("b")); 135 touch(msp2.resolve("b/module-info.java")); 136 touch(msp2.resolve("c/module-info.java")); 137 138 Path mp = base.resolve("mp"); 139 Path mp1 = mp.resolve("1"); 140 Path mp2 = mp.resolve("2"); 141 142 touch(mp1.resolve("a/module-info.class"), 143 mp1.resolve("b/module-info.class"), 144 mp2.resolve("b/module-info.class"), 145 mp2.resolve("c/module-info.class")); 146 147 Path so = base.resolve("so"); 148 149 Files.createDirectories(so.resolve("a")); 150 Files.createDirectories(so.resolve("b")); 151 152 List<String> mspOpt = Arrays.asList(msp1.toAbsolutePath().toString() + 153 File.pathSeparatorChar + 154 msp2.toAbsolutePath().toString()); 155 156 List<String> mpOpt = Arrays.asList(mp1.toAbsolutePath().toString() + 157 File.pathSeparatorChar + 158 mp2.toAbsolutePath().toString()); 159 160 fm.handleOption("--module-source-path", mspOpt.iterator()); 161 fm.handleOption("--module-path", mpOpt.iterator()); 162 fm.handleOption("-s", Arrays.asList(so.toString()).iterator()); 163 164 test.run(base, fm); 165 } 166 } 167 168 private Set<String> toSet(String... values) { 169 return new HashSet<>(Arrays.asList(values)); 170 } 171 172 private void touch(Path... paths) throws IOException { 173 for (Path p : paths) { 174 Files.createDirectories(p.getParent()); 175 Files.newOutputStream(p).close(); 176 } 177 } 178 179 @SafeVarargs 180 private void assertLocations(Iterable<Set<Location>> locations, Set<String>... expected) { 181 List<Set<String>> actual = 182 StreamSupport.stream(locations.spliterator(), true) 183 .map(locs -> locs.stream() 184 .map(l -> toString(l)) 185 .collect(Collectors.toSet())) 186 .collect(Collectors.toList()); 187 188 if (!Objects.equals(actual, Arrays.asList(expected))) { 189 throw new AssertionError("Unexpected output: " + actual); 190 } 191 } 192 193 private void assertRefused(Callable r) throws Exception { 194 try { 195 r.call(); 196 throw new AssertionError("Expected exception did not occur"); 197 } catch (IllegalArgumentException ex) { 198 //ok 199 } 200 } 201 202 private static String toString(Location l) { 203 return l.getName().replaceAll("\\[([0-9])\\.[0-9]:", "[$1.X,") + ":" + 204 l.isModuleOrientedLocation() + ":" + l.isOutputLocation(); 205 } 206 207 static interface TestExec { 208 public void run(Path base, JavaFileManager fm) throws Exception; 209 } 210 211 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 212} 213