3333import java .util .stream .Collectors ;
3434
3535import javax .lang .model .element .Element ;
36+ import javax .lang .model .element .PackageElement ;
37+ import javax .lang .model .element .TypeElement ;
3638
3739import com .sun .source .doctree .DocTree ;
3840import com .sun .source .doctree .LiteralTree ;
4446import static com .sun .source .doctree .DocTree .Kind .*;
4547
4648/**
47- * A base class for block tags to insert a link to an external copy of JLS or JVMS.
49+ * A base class for block tags to insert a link to a local copy of JLS or JVMS.
4850 * The tags can be used as follows:
4951 *
5052 * <pre>
5759 * @jls 3.4 Line Terminators
5860 * </pre>
5961 *
60- * will produce the following HTML for a docs build configured for Java SE 12.
62+ * will produce the following HTML, depending on the file containing
63+ * the tag.
6164 *
6265 * <pre>{@code
6366 * <dt>See <i>Java Language Specification</i>:
64- * <dd><a href="https://docs.oracle.com/javase/ specs/jls/se12/html /jls-3.html#jls-3.4">3.4 Line terminators</a>
67+ * <dd><a href="../../ specs/jls/jls-3.html#jls-3.4">3.4 Line terminators</a>
6568 * }</pre>
6669 *
67- * The version of the spec must be set in the jspec.version system property.
70+ * Copies of JLS and JVMS are expected to have been placed in the {@code specs}
71+ * folder. These documents are not included in open-source repositories.
6872 */
6973public class JSpec implements Taglet {
70- static final String SPEC_VERSION ;
71-
72- static {
73- SPEC_VERSION = System .getProperty ("jspec.version" );
74- if (SPEC_VERSION == null ) {
75- throw new RuntimeException ("jspec.version property not set" );
76- }
77- }
7874
7975 public static class JLS extends JSpec {
8076 public JLS () {
8177 super ("jls" ,
8278 "Java Language Specification" ,
83- "https://docs.oracle.com/javase/specs/jls/se" + SPEC_VERSION + "/html" ,
8479 "jls" );
8580 }
8681 }
@@ -89,20 +84,17 @@ public static class JVMS extends JSpec {
8984 public JVMS () {
9085 super ("jvms" ,
9186 "Java Virtual Machine Specification" ,
92- "https://docs.oracle.com/javase/specs/jvms/se" + SPEC_VERSION + "/html" ,
9387 "jvms" );
9488 }
9589 }
9690
9791 private String tagName ;
9892 private String specTitle ;
99- private String baseURL ;
10093 private String idPrefix ;
10194
102- JSpec (String tagName , String specTitle , String baseURL , String idPrefix ) {
95+ JSpec (String tagName , String specTitle , String idPrefix ) {
10396 this .tagName = tagName ;
10497 this .specTitle = specTitle ;
105- this .baseURL = baseURL ;
10698 this .idPrefix = idPrefix ;
10799 }
108100
@@ -169,8 +161,8 @@ public String toString(List<? extends DocTree> tags, Element elem) {
169161 String chapter = m .group ("chapter" );
170162 String section = m .group ("section" );
171163
172- String url = String .format ("%1$s/%2$s-%3$s.html#%2$s-%3$s%4$s" ,
173- baseURL , idPrefix , chapter , section );
164+ String url = String .format ("%1$s/../specs/%2$s/ %2$s-%3$s.html#%2$s-%3$s%4$s" ,
165+ docRoot ( elem ) , idPrefix , chapter , section );
174166
175167 sb .append ("<a href=\" " )
176168 .append (url )
@@ -216,4 +208,35 @@ private String escape(String s) {
216208 }
217209 }).visit (trees , new StringBuilder ()).toString ();
218210 }
211+
212+ private String docRoot (Element elem ) {
213+ switch (elem .getKind ()) {
214+ case MODULE :
215+ return ".." ;
216+
217+ case PACKAGE :
218+ PackageElement pe = (PackageElement )elem ;
219+ String pkgPart = pe .getQualifiedName ()
220+ .toString ()
221+ .replace ('.' , '/' )
222+ .replaceAll ("[^/]+" , ".." );
223+ return pe .getEnclosingElement () != null
224+ ? "../" + pkgPart
225+ : pkgPart ;
226+
227+ case CLASS , ENUM , RECORD , INTERFACE , ANNOTATION_TYPE :
228+ TypeElement te = (TypeElement )elem ;
229+ return te .getQualifiedName ()
230+ .toString ()
231+ .replace ('.' , '/' )
232+ .replaceAll ("[^/]+" , ".." );
233+
234+ default :
235+ var enclosing = elem .getEnclosingElement ();
236+ if (enclosing == null )
237+ throw new IllegalArgumentException (elem .getKind ().toString ());
238+ return docRoot (enclosing );
239+ }
240+ }
241+
219242}
0 commit comments