IncludeExcludePatterns.java revision 3195:88a874f33d6d
1163953Srrs/*
2169382Srrs * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3218319Srrs * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4218319Srrs *
5163953Srrs * This code is free software; you can redistribute it and/or modify it
6163953Srrs * under the terms of the GNU General Public License version 2 only, as
7163953Srrs * published by the Free Software Foundation.
8163953Srrs *
9163953Srrs * This code is distributed in the hope that it will be useful, but WITHOUT
10163953Srrs * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11163953Srrs * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12163953Srrs * version 2 for more details (a copy is included in the LICENSE file that
13163953Srrs * accompanied this code).
14163953Srrs *
15163953Srrs * You should have received a copy of the GNU General Public License version
16163953Srrs * 2 along with this work; if not, write to the Free Software Foundation,
17163953Srrs * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18163953Srrs *
19163953Srrs * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20163953Srrs * or visit www.oracle.com if you need additional information or have any
21163953Srrs * questions.
22163953Srrs */
23163953Srrs
24163953Srrs/*
25163953Srrs * @test
26163953Srrs * @bug 8037085
27163953Srrs * @summary Ensures that sjavac can handle various exclusion patterns.
28163953Srrs *
29163953Srrs * @modules jdk.compiler/com.sun.tools.sjavac
30163953Srrs * @library /tools/lib
31163953Srrs * @build Wrapper ToolBox
32163953Srrs * @run main Wrapper IncludeExcludePatterns
33163953Srrs */
34163953Srrs
35163953Srrsimport com.sun.tools.javac.util.Assert;
36163957Srrsimport com.sun.tools.sjavac.server.Sjavac;
37163953Srrs
38163953Srrsimport java.io.IOException;
39167598Srrsimport java.nio.file.Files;
40163953Srrsimport java.nio.file.Path;
41163953Srrsimport java.nio.file.Paths;
42163953Srrsimport java.util.Arrays;
43163953Srrsimport java.util.Collection;
44163953Srrsimport java.util.HashSet;
45172091Srrsimport java.util.Set;
46163953Srrsimport java.util.stream.Collectors;
47163953Srrsimport java.util.stream.Stream;
48163953Srrs
49163953Srrspublic class IncludeExcludePatterns extends SjavacBase {
50163953Srrs
51163953Srrs    final Path SRC = Paths.get("src");
52163953Srrs    final Path BIN = Paths.get("bin");
53163953Srrs    final Path STATE_DIR = Paths.get("state-dir");
54163953Srrs
55163953Srrs    // An arbitrarily but sufficiently complicated source tree.
56169420Srrs    final Path A = Paths.get("pkga/A.java");
57163953Srrs    final Path X1 = Paths.get("pkga/subpkg/Xx.java");
58163953Srrs    final Path Y = Paths.get("pkga/subpkg/subsubpkg/Y.java");
59163953Srrs    final Path B = Paths.get("pkgb/B.java");
60221249Stuexen    final Path C = Paths.get("pkgc/C.java");
61221249Stuexen    final Path X2 = Paths.get("pkgc/Xx.java");
62163953Srrs
63163953Srrs    final Path[] ALL_PATHS = {A, X1, Y, B, C, X2};
64221249Stuexen
65163953Srrs    public static void main(String[] ignore) throws Exception {
66163953Srrs        new IncludeExcludePatterns().runTest();
67163953Srrs    }
68163953Srrs
69163953Srrs    public void runTest() throws IOException, ReflectiveOperationException {
70163953Srrs        Files.createDirectories(BIN);
71221249Stuexen        Files.createDirectories(STATE_DIR);
72221249Stuexen        for (Path p : ALL_PATHS) {
73221249Stuexen            writeDummyClass(p);
74221249Stuexen        }
75221249Stuexen
76221249Stuexen        // Single file
77221249Stuexen        testPattern("pkga/A.java", A);
78221249Stuexen
79221249Stuexen        // Leading wild cards
80221249Stuexen        testPattern("*/A.java", A);
81221249Stuexen        testPattern("**/Xx.java", X1, X2);
82221249Stuexen        testPattern("**x.java", X1, X2);
83221249Stuexen
84221249Stuexen        // Wild card in middle of path
85163953Srrs        testPattern("pkga/*/Xx.java", X1);
86221249Stuexen        testPattern("pkga/**/Y.java", Y);
87221249Stuexen
88221249Stuexen        // Trailing wild cards
89221249Stuexen        testPattern("pkga/*", A);
90163953Srrs        testPattern("pkga/**", A, X1, Y);
91221249Stuexen
92221249Stuexen        // Multiple wildcards
93221249Stuexen        testPattern("pkga/*/*/Y.java", Y);
94221249Stuexen        testPattern("**/*/**", X1, Y);
95221249Stuexen
96221249Stuexen    }
97221249Stuexen
98221249Stuexen    // Given "src/pkg/subpkg/A.java" this method returns "A"
99221249Stuexen    String classNameOf(Path javaFile) {
100221249Stuexen        return javaFile.getFileName()
101221249Stuexen                       .toString()
102221249Stuexen                       .replace(".java", "");
103163953Srrs    }
104221249Stuexen
105163953Srrs    // Puts an empty (dummy) class definition in the given path.
106163953Srrs    void writeDummyClass(Path javaFile) throws IOException {
107163953Srrs        String pkg = javaFile.getParent().toString().replace('/', '.');
108163953Srrs        String cls = javaFile.getFileName().toString().replace(".java", "");
109163953Srrs        toolbox.writeFile(SRC.resolve(javaFile), "package " + pkg + "; class " + cls + " {}");
110163953Srrs    }
111163953Srrs
112163953Srrs    void testPattern(String filterArgs, Path... sourcesExpectedToBeVisible)
113171477Srrs            throws ReflectiveOperationException, IOException {
114171477Srrs        testFilter("-i " + filterArgs, Arrays.asList(sourcesExpectedToBeVisible));
115171477Srrs
116171477Srrs        Set<Path> complement = new HashSet<>(Arrays.asList(ALL_PATHS));
117171477Srrs        complement.removeAll(Arrays.asList(sourcesExpectedToBeVisible));
118171477Srrs        testFilter("-x " + filterArgs, complement);
119163953Srrs    }
120163953Srrs
121163953Srrs    void testFilter(String filterArgs, Collection<Path> sourcesExpectedToBeVisible)
122163953Srrs            throws IOException, ReflectiveOperationException {
123163953Srrs        System.out.println("Testing filter: " + filterArgs);
124163953Srrs        toolbox.cleanDirectory(BIN);
125171477Srrs        toolbox.cleanDirectory(STATE_DIR);
126171477Srrs        String args = filterArgs + " " + SRC
127171477Srrs                + " --server:portfile=testportfile,background=false"
128171477Srrs                + " -d " + BIN
129163953Srrs                + " --state-dir=" + STATE_DIR;
130163953Srrs        int rc = compile((Object[]) args.split(" "));
131163953Srrs
132163953Srrs        // Compilation should always pass in these tests
133163953Srrs        Assert.check(rc == Sjavac.RC_OK, "Compilation failed unexpectedly.");
134163953Srrs
135163953Srrs        // The resulting .class files should correspond to the visible source files
136163953Srrs        Set<Path> result = allFilesInDir(BIN);
137163953Srrs        Set<Path> expected = correspondingClassFiles(sourcesExpectedToBeVisible);
138163953Srrs        if (!result.equals(expected)) {
139169420Srrs            System.out.println("Result:");
140169420Srrs            printPaths(result);
141163953Srrs            System.out.println("Expected:");
142163953Srrs            printPaths(expected);
143163953Srrs            Assert.error("Test case failed: " + filterArgs);
144163953Srrs        }
145163953Srrs    }
146163953Srrs
147165647Srrs    void printPaths(Collection<Path> paths) {
148163953Srrs        paths.stream()
149163953Srrs             .sorted()
150163953Srrs             .forEachOrdered(p -> System.out.println("    " + p));
151163953Srrs    }
152163953Srrs
153163953Srrs    // Given "pkg/A.java, pkg/B.java" this method returns "bin/pkg/A.class, bin/pkg/B.class"
154163953Srrs    Set<Path> correspondingClassFiles(Collection<Path> javaFiles) {
155163953Srrs        return javaFiles.stream()
156163953Srrs                        .map(javaFile -> javaFile.resolveSibling(classNameOf(javaFile) + ".class"))
157163953Srrs                        .map(BIN::resolve)
158163953Srrs                        .collect(Collectors.toSet());
159163953Srrs    }
160163953Srrs
161163953Srrs    Set<Path> allFilesInDir(Path p) throws IOException {
162163953Srrs        try (Stream<Path> files = Files.walk(p).filter(Files::isRegularFile)) {
163163953Srrs            return files.collect(Collectors.toSet());
164163953Srrs        }
165163953Srrs    }
166163953Srrs}
167169420Srrs