1/*
2 * Copyright (c) 2015, 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 8035473 8154482 8154399 8159096 8176131 8176331 8177511
27 * @summary make sure the javadoc tool responds correctly,
28 *          to old and new doclet implementations.
29 * @library /tools/lib
30 * @build toolbox.ToolBox toolbox.TestRunner
31 * @run main EnsureNewOldDoclet
32 */
33
34import java.io.*;
35import java.nio.file.Path;
36import java.util.Arrays;
37import java.util.Collections;
38import java.util.List;
39import java.util.Map;
40import java.util.Set;
41import java.util.regex.Pattern;
42import java.util.stream.Collectors;
43import javax.lang.model.element.Element;
44
45import com.sun.javadoc.Tag;
46import com.sun.source.doctree.DocTree;
47
48import toolbox.*;
49
50
51/**
52 * This test ensures the doclet responds correctly when given
53 * various conditions that force a fall back to the old javadoc
54 * tool.
55 */
56public class EnsureNewOldDoclet extends TestRunner {
57
58    final ToolBox tb;
59    final File testSrc;
60    final Path javadocPath;
61    final ExecTask task;
62    final String testClasses;
63    final PrintStream ostream;
64
65    final static String CLASS_NAME = "EnsureNewOldDoclet";
66    final static String OLD_DOCLET_CLASS_NAME = CLASS_NAME + "$OldDoclet";
67    final static String NEW_DOCLET_CLASS_NAME = CLASS_NAME + "$NewDoclet"; //unused
68    final static String NEW_TAGLET_CLASS_NAME = CLASS_NAME + "$NewTaglet";
69
70    final static Pattern OLD_HEADER = Pattern.compile(".*This is not the Standard Doclet.*");
71    final static Pattern NEW_HEADER = Pattern.compile("^Standard Doclet version.*");
72
73
74    final static String OLD_DOCLET_MARKER = "OLD_DOCLET_MARKER";
75
76    final static String NEW_DOCLET_MARKER = "NEW_DOCLET_MARKER";
77    final static String NEW_TAGLET_MARKER = "Registered Taglet " + CLASS_NAME + "\\$NewTaglet";
78
79    final static Pattern WARN_TEXT = Pattern.compile("Users are strongly recommended to migrate" +
80                                                    " to the new APIs.");
81
82    final static String NEW_STDDOCLET = "jdk.javadoc.doclet.StandardDoclet";
83
84
85    public EnsureNewOldDoclet() throws Exception {
86        super(System.err);
87        ostream = System.err;
88        testClasses = System.getProperty("test.classes");
89        tb = new ToolBox();
90        javadocPath = tb.getJDKTool("javadoc");
91        task = new ExecTask(tb, javadocPath);
92        testSrc = new File("Foo.java");
93        generateSample(testSrc);
94    }
95
96    void generateSample(File testSrc) throws Exception {
97        String nl = System.getProperty("line.separator");
98        String src = Arrays.asList(
99            "/**",
100            " * A test class to test javadoc. Nothing more nothing less.",
101            " */",
102            " public class Foo{}").stream().collect(Collectors.joining(nl));
103        tb.writeFile(testSrc.getPath(), src);
104    }
105
106    public static void main(String... args) throws Exception {
107        new EnsureNewOldDoclet().runTests();
108    }
109
110    // input: nothing, default mode
111    // outcome: new tool and new doclet
112    @Test
113    public void testDefault() throws Exception {
114        setArgs("-classpath", ".", // insulates us from ambient classpath
115                  testSrc.toString());
116        Task.Result tr = task.run(Task.Expect.SUCCESS);
117        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
118        checkOutput(testName, out, NEW_HEADER);
119    }
120
121    // input: old doclet
122    // outcome: old tool
123    @Test
124    public void testOldDoclet() throws Exception {
125        setArgs("-classpath", ".", // ambient classpath insulation
126                "-doclet",
127                OLD_DOCLET_CLASS_NAME,
128                "-docletpath",
129                testClasses,
130                testSrc.toString());
131        Task.Result tr = task.run(Task.Expect.SUCCESS);
132        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
133        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
134        checkOutput(testName, out, OLD_DOCLET_MARKER);
135        checkOutput(testName, err, WARN_TEXT);
136    }
137
138    // input: new doclet and new taglet
139    // outcome: new doclet and new taglet should register
140    @Test
141    public void testNewDocletNewTaglet() throws Exception {
142        setArgs("-classpath", ".", // ambient classpath insulation
143                "-doclet",
144                NEW_STDDOCLET,
145                "-taglet",
146                NEW_TAGLET_CLASS_NAME,
147                "-tagletpath",
148                testClasses,
149                testSrc.toString());
150        Task.Result tr = task.run(Task.Expect.SUCCESS);
151        List<String> out = tr.getOutputLines(Task.OutputKind.STDOUT);
152        List<String> err = tr.getOutputLines(Task.OutputKind.STDERR);
153        checkOutput(testName, out, NEW_HEADER);
154        checkOutput(testName, out, NEW_TAGLET_MARKER);
155    }
156
157    void setArgs(String... args) {
158        ostream.println("cmds: " + Arrays.asList(args));
159        task.args(args);
160    }
161
162    void checkOutput(String testCase, List<String> content, String toFind) throws Exception {
163        checkOutput(testCase, content, Pattern.compile(".*" + toFind + ".*"));
164    }
165
166    void checkOutput(String testCase, List<String> content, Pattern toFind) throws Exception {
167        ostream.println("---" + testCase + "---");
168        content.stream().forEach(x -> System.out.println(x));
169        for (String x : content) {
170            ostream.println(x);
171            if (toFind.matcher(x).matches()) {
172                return;
173            }
174        }
175        throw new Exception(testCase + ": Expected string not found: " +  toFind);
176    }
177
178    public static class OldDoclet extends com.sun.javadoc.Doclet {
179        public static boolean start(com.sun.javadoc.RootDoc root) {
180            System.out.println(OLD_DOCLET_MARKER);
181            return true;
182        }
183    }
184
185    public static class NewTaglet implements jdk.javadoc.doclet.Taglet {
186
187        @Override
188        public Set<Location> getAllowedLocations() {
189            return Collections.emptySet();
190        }
191
192        @Override
193        public boolean isInlineTag() {
194            return true;
195        }
196
197        @Override
198        public String getName() {
199            return "NewTaglet";
200        }
201
202        @Override
203        public String toString(List<? extends DocTree> tags, Element element) {
204            return tags.toString();
205        }
206
207    }
208}
209