1/*
2 * Copyright (c) 2016, 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 8159305 8167383
27 * @summary Tests elements filtering options
28 * @modules
29 *      jdk.javadoc/jdk.javadoc.internal.api
30 *      jdk.javadoc/jdk.javadoc.internal.tool
31 *      jdk.compiler/com.sun.tools.javac.api
32 *      jdk.compiler/com.sun.tools.javac.main
33 * @library /tools/lib
34 * @build toolbox.ToolBox toolbox.TestRunner
35 * @run main FilterOptions
36 */
37
38import java.io.IOException;
39import java.nio.file.Path;
40import java.nio.file.Paths;
41
42import toolbox.*;
43
44public class FilterOptions extends ModuleTestBase {
45
46    private static final String NL = System.getProperty("line.separator");
47    private static final String INDENT = "    ";
48
49    // the sources are shared, so create it once
50    private final String src;
51
52    public static void main(String... args) throws Exception {
53        new FilterOptions().runTests();
54    }
55
56    FilterOptions() throws IOException {
57        this.src = createSources(Paths.get(".").resolve("src"));
58    }
59
60    @Test
61    public void testDefault(Path base) throws Exception {
62        execTask("--module-source-path", src, "--module", "m1");
63
64        checkModulesSpecified("m1");
65        checkModulesIncluded("m1");
66        checkPackagesIncluded("pub");
67        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
68    }
69
70    @Test
71    public void testModuleModeApi(Path base) throws Exception {
72        execTask("--module-source-path", src,
73                "--module", "m1", "--show-module-contents", "api");
74
75        checkModuleMode("API");
76        checkModulesSpecified("m1");
77        checkModulesIncluded("m1");
78        checkPackagesIncluded("pub");
79        checkPackagesNotIncluded("pro", "pqe");
80    }
81
82    @Test
83    public void testModuleModeAll(Path base) throws Exception {
84        execTask("--module-source-path", src,
85                "--module", "m1", "--show-module-contents", "all");
86
87        checkModuleMode("ALL");
88        checkModulesSpecified("m1");
89        checkModulesIncluded("m1");
90        checkPackagesIncluded("pub", "pqe");
91        checkPackagesNotIncluded("pro");
92    }
93
94    @Test
95    public void testShowPackagesExported(Path base)  throws Exception {
96        execTask("--module-source-path", src,
97                "--module", "m1",
98                "--show-packages", "exported"); // default
99
100        checkModulesSpecified("m1");
101        checkModulesIncluded("m1");
102        checkPackagesIncluded("pub");
103        checkPackagesNotIncluded("pqe", "pro");
104        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
105    }
106
107    @Test
108    public void testShowPackagesAll(Path base) throws Exception {
109        execTask("--module-source-path", src,
110                "--module", "m1",
111                "--show-packages", "all");
112        checkModulesSpecified("m1");
113        checkModulesIncluded("m1");
114        checkPackagesIncluded("pub", "pqe", "pro");
115
116        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
117                           "pqe.A", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
118                           "pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
119    }
120
121    @Test
122    public void testShowTypesPrivate(Path base) throws Exception {
123        execTask("--module-source-path", src,
124                "--module", "m1",
125                "--show-types", "private");
126
127        checkModulesSpecified("m1");
128        checkModulesIncluded("m1");
129        checkPackagesIncluded("pub");
130
131        checkTypesIncluded("pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
132                           "pub.A.PublicNested",
133                           "pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
134                           "pub.B.PublicNested");
135
136    }
137
138    @Test
139    public void testShowTypesPackage(Path base) throws Exception {
140        execTask("--module-source-path", src,
141                "--module", "m1",
142                "--show-types", "package");
143
144        checkModulesSpecified("m1");
145        checkModulesIncluded("m1");
146        checkPackagesIncluded("pub");
147
148        checkTypesIncluded("pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
149                           "pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested");
150
151        checkTypesNotIncluded(".*private.*");
152    }
153
154    @Test
155    public void testShowTypesProtected(Path base) throws Exception {
156        execTask("--module-source-path", src,
157                "--module", "m1",
158                "--show-types", "protected");
159
160        checkModulesSpecified("m1");
161        checkModulesIncluded("m1");
162        checkPackagesIncluded("pub");
163
164        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
165
166        checkTypesNotIncluded("pub.A.Nested", "pub.A.PrivateNested", "pub.B.Nested",
167                              "pub.B.PrivateNested", "pub.B.ProtectedNested",
168                              "pub.B.PublicNested");
169    }
170
171    @Test
172    public void testShowTypesPublic(Path base) throws Exception {
173        execTask("--module-source-path", src,
174                "--module", "m1",
175                "--show-types", "public");
176
177        checkModulesSpecified("m1");
178        checkModulesIncluded("m1");
179        checkPackagesIncluded("pub");
180
181        checkTypesIncluded("pub.A", "pub.A.PublicNested");
182        checkTypesNotIncluded("pub.A.Nested",
183                              "pub.A.ProtectedNested", "pub.A.PrivateNested",
184                              "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PrivateNested",
185                              "pub.B.PublicNested");
186    }
187
188    @Test
189    public void testShowMembersPrivate(Path base) throws Exception {
190        execTask("--module-source-path", src,
191                "--module", "m1",
192                "--show-members", "private");
193
194        checkMembers(Visibility.PRIVATE);
195    }
196
197    @Test
198    public void testShowMembersPackage(Path base) throws Exception {
199        execTask("--module-source-path", src,
200                "--module", "m1",
201                "--show-members", "package");
202
203        checkMembers(Visibility.PACKAGE);
204    }
205
206    @Test
207    public void testShowMembersProtected(Path base) throws Exception {
208        execTask("--module-source-path", src,
209                "--module", "m1",
210                "--show-members", "protected");
211
212        checkMembers(Visibility.PROTECTED);
213    }
214
215    @Test
216    public void testShowMembersPublic(Path base) throws Exception {
217        execTask("--module-source-path", src,
218                "--module", "m1",
219                "--show-members", "public");
220
221        checkMembers(Visibility.PUBLIC);
222    }
223
224    @Test
225    public void testLegacyPublic(Path base) throws Exception {
226        execTask("--module-source-path", src,
227                "--module", "m1",
228                "-public");
229
230        checkModuleMode("API");
231        checkModulesSpecified("m1");
232        checkModulesIncluded("m1");
233        checkPackagesIncluded("pub");
234        checkPackagesNotIncluded("pqe", "pro");
235        checkTypesIncluded("pub.A", "pub.A.PublicNested");
236
237        checkMembers(Visibility.PUBLIC);
238    }
239
240    @Test
241    public void testLegacyDefault(Path base) throws Exception {
242        execTask("--module-source-path", src,
243                "--module", "m1");
244
245        checkModuleMode("API");
246        checkModulesSpecified("m1");
247        checkModulesIncluded("m1");
248        checkPackagesIncluded("pub");
249        checkPackagesNotIncluded("pqe", "pro");
250        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
251
252        checkMembers(Visibility.PROTECTED);
253    }
254
255    @Test
256    public void testLegacyProtected(Path base) throws Exception {
257        execTask("--module-source-path", src,
258                "--module", "m1",
259                "-protected");
260
261        checkModuleMode("API");
262        checkModulesSpecified("m1");
263        checkModulesIncluded("m1");
264        checkPackagesIncluded("pub");
265        checkPackagesNotIncluded("pqe", "pro");
266        checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
267
268        checkMembers(Visibility.PROTECTED);
269    }
270
271    @Test
272    public void testLegacyPackage(Path base) throws Exception {
273        execTask("--module-source-path", src,
274                "--module", "m1",
275                "-package");
276
277        checkModuleMode("ALL");
278        checkModulesSpecified("m1");
279        checkModulesIncluded("m1");
280        checkPackagesIncluded("pub", "pqe", "pro");
281        checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
282                           "pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
283                           "pqe.A", "pqe.A.Nested", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
284                           "pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
285                           "pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
286
287        checkMembers(Visibility.PACKAGE);
288    }
289
290    @Test
291    public void testLegacyPrivate(Path base) throws Exception {
292        execTask("--module-source-path", src,
293                "--module", "m1",
294                "-private");
295
296        checkModuleMode("ALL");
297        checkModulesSpecified("m1");
298        checkModulesIncluded("m1");
299        checkPackagesIncluded("pub", "pqe", "pro");
300        checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
301                           "pub.B.PublicNested",
302                           "pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
303                           "pub.A.PublicNested",
304                           "pqe.A", "pqe.A.PrivateNested", "pqe.A.Nested", "pqe.A.ProtectedNested",
305                           "pqe.A.PublicNested",
306                           "pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
307                           "pro.B.PublicNested",
308                           "pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
309                           "pro.A.PublicNested");
310
311        checkMembers(Visibility.PRIVATE);
312    }
313
314    private static enum Visibility {
315        PRIVATE, PACKAGE, PROTECTED, PUBLIC;
316    }
317
318    void checkMembers(Visibility v) throws Exception {
319        checkMembersPresence(v);
320        checkMembersAbsence(v);
321    }
322
323    void checkMembersPresence(Visibility v) throws Exception {
324        switch (v) {
325            case PRIVATE:
326                checkMembersSelected("pub.A.privateFieldA",
327                                     "pub.A.PublicNested.privateFieldPublicNested",
328                                     "pub.A.ProtectedNested.privateFieldProtectedNested");
329
330            case PACKAGE:
331                checkMembersSelected("pub.A.FieldA",
332                                     "pub.A.PublicNested.FieldPublicNested",
333                                     "pub.A.ProtectedNested.FieldProtectedNested");
334
335            case PROTECTED:
336                checkMembersSelected("pub.A.<init>",
337                                     "pub.A.protectedFieldA",
338                                     "pub.A.PublicNested.protectedFieldPublicNested",
339                                     "pub.A.ProtectedNested.<init>",
340                                     "pub.A.ProtectedNested.protectedFieldProtectedNested",
341                                     "pub.A.ProtectedNested.publicFieldProtectedNested");
342
343            case PUBLIC:
344                checkMembersSelected("pub.A.publicFieldA",
345                                     "pub.A.PublicNested.<init>",
346                                     "pub.A.PublicNested.publicFieldPublicNested");
347
348                break;
349        }
350    }
351
352    void checkMembersAbsence(Visibility v) throws Exception {
353        switch (v) {
354            case PUBLIC:
355                checkMembersNotSelected("pub.A.protectedFieldA",
356                                        "pub.A.PublicNested.protectedFieldPublicNested",
357                                        "pub.A.ProtectedNested.<init>",
358                                        "pub.A.ProtectedNested.protectedFieldProtectedNested");
359
360            case PROTECTED:
361                checkMembersNotSelected("pub.A.FieldA",
362                                        "pub.A.PublicNested.FieldPublicNested",
363                                        "pub.A.ProtectedNested.FieldProtectedNested");
364
365            case PACKAGE:
366                checkMembersNotSelected("pub.A.privateFieldA",
367                                        "pub.A.PublicNested.privateFieldPublicNested",
368                                        "pub.A.ProtectedNested.privateFieldProtectedNested");
369
370            case PRIVATE:
371                break;
372        }
373    }
374
375    String createSources(Path src) throws IOException {
376        ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
377        mb1.comment("The first module.")
378                .classes(createClass("pub", "A", true))
379                .classes(createClass("pub", "B", false))
380                .classes(createClass("pro", "A", true))
381                .classes(createClass("pro", "B", false))
382                .classes(createClass("pqe", "A", true))
383                .exports("pub")
384                .exportsTo("pqe", "m2")
385                .write(src);
386
387        ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
388        mb2.comment("The second module")
389                .classes(createClass("m2pub", "A", true))
390                .requires("m1")
391                .write(src);
392
393        return src.toString();
394    }
395
396    String createClass(String pkg, String name, boolean isPublic) {
397        StringBuilder sb = new StringBuilder("package ")
398                .append(pkg)
399                .append("; ")
400                .append(NL);
401        sb.append(" /** Klass ")
402                .append(name)
403                .append(" */")
404                .append(NL);
405        sb.append(isPublic ? "public " : " ")
406                .append("class ")
407                .append(name)
408                .append(" {")
409                .append(NL);
410
411        sb.append(createMembers(INDENT, name));
412        sb.append(createNestedClass(INDENT, "PublicNested", name, "public"));
413        sb.append(createNestedClass(INDENT, "ProtectedNested", name, "protected"));
414        sb.append(createNestedClass(INDENT, "Nested", name, ""));
415        sb.append(createNestedClass(INDENT, "PrivateNested", name, "private"));
416
417        return sb.append("}").toString();
418    }
419
420    StringBuilder createNestedClass(String indent, String name, String enclosing, String visibility) {
421        return new StringBuilder()
422                .append(indent).append(" /** Klass ").append(name).append(" */").append(NL)
423                .append(indent).append(visibility).append(" class ").append(name).append(" {").append(NL)
424                .append(createMembers(indent + INDENT, name)).append(indent).append("}").append(NL);
425    }
426
427    StringBuilder createMembers(String indent, String enclosing) {
428        return new StringBuilder()
429                .append(indent).append(createMember(enclosing, "public"))
430                .append(indent).append(createMember(enclosing, "protected"))
431                .append(indent).append(createMember(enclosing, ""))
432                .append(indent).append(createMember(enclosing, "private"))
433                .append(NL);
434    }
435
436    StringBuilder createMember(String enclosingClass, String visibility) {
437        return new StringBuilder()
438                .append("/** a ")
439                .append(visibility)
440                .append("Field in ")
441                .append(enclosingClass)
442                .append(" */ ")
443                .append(visibility)
444                .append(" String ")
445                .append(visibility)
446                .append("Field")
447                .append(enclosingClass)
448                .append(";")
449                .append(NL);
450    }
451}
452