Skip to content

Commit

Permalink
Compute JavaDoc URLs lazily
Browse files Browse the repository at this point in the history
Optimized the map away since the method is rarely called and the bottle
neck would be likely the IO code before the computation anyway.
  • Loading branch information
mbien committed Oct 13, 2023
1 parent e010ac1 commit dd924bc
Showing 1 changed file with 45 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import java.net.URL;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -34,6 +34,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.lang.model.SourceVersion;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.java.platform.JavaPlatform;
import org.netbeans.modules.java.j2seplatform.spi.J2SEPlatformDefaultJavadoc;
Expand All @@ -42,70 +43,30 @@
import org.openide.util.lookup.ServiceProvider;

/**
* Default Javadoc for J2SE.
* Default Javadoc for Java.
* @author Tomas Zezula
*/
@ServiceProvider(service =J2SEPlatformDefaultJavadoc.class, position = 100, path = "org-netbeans-api-java/platform/j2seplatform/defaultJavadocProviders")
@ServiceProvider(service = J2SEPlatformDefaultJavadoc.class, position = 100, path = "org-netbeans-api-java/platform/j2seplatform/defaultJavadocProviders")
public final class J2SEPlatformDefaultJavadocImpl implements J2SEPlatformDefaultJavadoc {

private static final Logger LOG = Logger.getLogger(J2SEPlatformDefaultJavadocImpl.class.getName());
private static final Map<String,String> OFFICIAL_JAVADOC = new HashMap<>();
static {
OFFICIAL_JAVADOC.put("1.0", null); // NOI18N
OFFICIAL_JAVADOC.put("1.1", null); // NOI18N
OFFICIAL_JAVADOC.put("1.2", null); // NOI18N
OFFICIAL_JAVADOC.put("1.3", null); // NOI18N
OFFICIAL_JAVADOC.put("1.4", null); // NOI18N
OFFICIAL_JAVADOC.put("1.5", "https://docs.oracle.com/javase/1.5.0/docs/api/"); // NOI18N
OFFICIAL_JAVADOC.put("1.6", "https://docs.oracle.com/javase/6/docs/api/"); // NOI18N
OFFICIAL_JAVADOC.put("1.7", "https://docs.oracle.com/javase/7/docs/api/"); // NOI18N
OFFICIAL_JAVADOC.put("1.8", "https://docs.oracle.com/javase/8/docs/api/"); // NOI18N

// timezone shouldn't matter since the accuracy is worse than a day
LocalDate jdk9 = LocalDate.of(2017, Month.SEPTEMBER, 21); // start of 6 month schedule
LocalDate now = LocalDate.now();

if (now.isAfter(jdk9)) { // time traveler -> only java 8 doc for you
int jdk = 9;
LocalDate jdkEarly = jdk9;
for (LocalDate t = jdk9 ; t.isBefore(now); t = t.plusMonths(6)) {
OFFICIAL_JAVADOC.put(String.valueOf(jdk), "https://docs.oracle.com/en/java/javase/" + jdk + "/docs/api/"); // NOI18N
jdkEarly = t;
jdk++;
}

jdkEarly = jdkEarly.minusDays(12);

if (now.isAfter(jdkEarly)) {
OFFICIAL_JAVADOC.put(String.valueOf(jdk), "https://download.java.net/java/early_access/jdk" + jdk + "/docs/api/"); // NOI18N Early access
jdkEarly = jdkEarly.plusMonths(3);
jdk++;
}
// there is a 2nd jdk early release after 3 months
if (now.isAfter(jdkEarly)) {
OFFICIAL_JAVADOC.put(String.valueOf(jdk), "https://download.java.net/java/early_access/jdk" + jdk + "/docs/api/"); // NOI18N Early access
}
}
}

@Override
public Collection<URI> getDefaultJavadoc(@NonNull final JavaPlatform platform) {
// local
final List<URI> result = new ArrayList<>();
final JavadocFilter filter = new JavadocFilter();
for (FileObject folder : platform.getInstallFolders()) {
for (FileObject file : folder.getChildren()) {
final Collection<? extends URI> roots = filter.accept(file);
result.addAll(roots);
result.addAll(filter.accept(file));
}
}
if (!result.isEmpty()) {
return Collections.unmodifiableList(result);
}
// remote
String version = platform.getSpecification().getVersion().toString();
if (!OFFICIAL_JAVADOC.containsKey(version)) {
LOG.log(Level.WARNING, "unrecognized Java spec version: {0}", version);
}
String location = OFFICIAL_JAVADOC.get(version);
String location = computeJavaDocURL(version);
if (location != null) {
try {
return Collections.singletonList(new URI(location));
Expand All @@ -116,6 +77,43 @@ public Collection<URI> getDefaultJavadoc(@NonNull final JavaPlatform platform) {
return Collections.emptyList();
}

private static String computeJavaDocURL(String version) {
switch (version) {
case "1.0": // NOI18N
case "1.1": // NOI18N
case "1.2": // NOI18N
case "1.3": // NOI18N
case "1.4": return null; // NOI18N
case "1.5": return "https://docs.oracle.com/javase/1.5.0/docs/api/"; // NOI18N
case "1.6": return "https://docs.oracle.com/javase/6/docs/api/"; // NOI18N
case "1.7": return "https://docs.oracle.com/javase/7/docs/api/"; // NOI18N
case "1.8": return "https://docs.oracle.com/javase/8/docs/api/"; // NOI18N
}
try {
int feature = Integer.parseInt(version);
if (feature >= 9) {
int latestGA = computeLatestGAVersion();
if (feature <= latestGA) {
return "https://docs.oracle.com/en/java/javase/" + feature + "/docs/api/"; // NOI18N
} else if (feature <= latestGA + 3) {
return "https://download.java.net/java/early_access/jdk" + feature + "/docs/api/"; // NOI18N
}
}
} catch (IllegalArgumentException ignore) {}
LOG.log(Level.WARNING, "unrecognized Java spec version: {0}", version); // NOI18N
return null;
}

/**
* Computes the feature version of the latest generally available JDK release.
*/
private static int computeLatestGAVersion() {
// timezone shouldn't matter since the accuracy is worse than a day
LocalDate jdk9 = LocalDate.of(2017, Month.SEPTEMBER, 21); // start of 6 month schedule
int latest = 9 + (int) (ChronoUnit.MONTHS.between(jdk9, LocalDate.now()) / 6);
return Math.max(latest, SourceVersion.latest().ordinal()); // in case system time is wrong, use nb-javac version as lower bound
}

private static final class JavadocFilter {
private static final Pattern DOCS_FILE_PATTERN = Pattern.compile(".*docs.*\\.(zip|jar)",Pattern.CASE_INSENSITIVE); //NOI18N
private static final Pattern JAVAFX_FILE_PATTERN = Pattern.compile(".*j(ava)?fx.*", Pattern.CASE_INSENSITIVE); //NOI18N
Expand Down

0 comments on commit dd924bc

Please sign in to comment.