diff --git a/app/data/javadoc.json b/app/data/javadoc.json
index d4a4f24..a22629c 100644
--- a/app/data/javadoc.json
+++ b/app/data/javadoc.json
@@ -1,8 +1,10 @@
{
- "current_release": "19",
+ "current_release": "23",
"java-documentation": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/",
+ "java-documentation-summary": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/api/java.naming/module-summary.html",
"javadoc_root": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/api/",
+ "jdk-release-note": "https://www.oracle.com/java/technologies/javase/jdk-relnotes-index.html",
"security-standard-names": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/security/standard-names.html",
"jre-jdk-cryptoroadmap": "https://www.java.com/en/jre-jdk-cryptoroadmap.html",
@@ -13,7 +15,7 @@
"jpackage": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jpackage.html",
"java-api-docs": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/api/index.html",
"specification": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/api/index.html",
- "release-notes": "https://www.oracle.com/java/technologies/javase/@@CURRENT_RELEASE@@-relnotes.html",
+ "release-notes": "https://www.oracle.com/java/technologies/javase/@@CURRENT_RELEASE@@u-relnotes.html",
"jvm-guide": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/vm/java-virtual-machine-technology-overview.html",
"gc-tuning": { "link": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/gctuning/introduction-garbage-collection-tuning.html",
@@ -52,6 +54,7 @@
"jmod": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jmod.html",
"jdeps": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jdeps.html",
"jdeprscan": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jdeprscan.html",
+ "jwebserver": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jwebserver.html",
"jfr": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jfr.html",
"jconsole": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jconsole.html",
"jps": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jps.html",
@@ -77,6 +80,10 @@
"rfc-5246": "https://www.ietf.org/rfc/rfc5246.html",
"rfc-8446": "https://www.ietf.org/rfc/rfc8446.html",
"rfc-8017": "https://www.ietf.org/rfc/rfc8017.html",
+ "rfc-8032": "https://tools.ietf.org/html/rfc8032",
+ "trec-x509": "https://www.itu.int/rec/T-REC-X.509/en",
+ "dss": "https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf",
+ "rfc-1422": "https://www.ietf.org/rfc/rfc1422.html",
"ANSI-20X9.62": "https://standards.globalspec.com/std/1955141/ANSI%20X9.62",
"ide-eclipse": "https://www.eclipseide.org/",
@@ -121,6 +128,8 @@
"Object.wait(long)": "java.base/java/lang/Object.html#wait(long)",
"Object.wait(long,int)": "java.base/java/lang/Object.html#wait(long,int)",
+ "ClassLoader": "java.base/java/lang/ClassLoader.html",
+
"NullPointerException": "java.base/java/lang/NullPointerException.html",
"Override": "java.base/java/lang/Override.html",
@@ -138,26 +147,17 @@
"Cloneable": "java.base/java/lang/Cloneable.html",
"CloneNotSupportedException": "java.base/java/lang/CloneNotSupportedException.html",
- "Class": "java.base/java/lang/Class.html",
- "Class.getFields()": "java.base/java/lang/Class.html#getFields()",
- "Class.getInterfaces()": "java.base/java/lang/Class.html#getInterfaces()",
- "Class.getMethods()": "java.base/java/lang/Class.html#getMethods()",
- "Class.getSimpleName()": "java.base/java/lang/Class.html#getSimpleName()",
- "Class.getSuperclass()": "java.base/java/lang/Class.html#getSuperclass()",
- "Class.isAnnotation()": "java.base/java/lang/Class.html#isAnnotation()",
- "Class.isEnum()": "java.base/java/lang/Class.html#isEnum()",
- "Class.isInterface()": "java.base/java/lang/Class.html#isInterface()",
-
"Record": "java.base/java/lang/Record.html",
"System": "java.base/java/lang/System.html",
"System.out": "java.base/java/lang/System.html#out",
"System.arraycopy(java.lang.Object,int,java.lang.Object,int,int)": "java.base/java/lang/System.html#arraycopy(java.lang.Object,int,java.lang.Object,int,int)",
+ "System.console()": "java.base/java/lang/System.html#console()",
"Long": "java.base/java/lang/Long.html",
"Long.compareTo(Long)": "java.base/java/lang/Long.html#compareTo(java.lang.Long)",
- "Long.compareUnsigned(int,int)": "java.base/java/lang/Long.html#compareUnsigned(int,int)",
- "Long.divideUnsigned(int,int)": "java.base/java/lang/Long.html#divideUnsigned(int,int)",
+ "Long.compareUnsigned(long,long)": "java.base/java/lang/Long.html#compareUnsigned(long,long)",
+ "Long.divideUnsigned(long,long)": "java.base/java/lang/Long.html#divideUnsigned(long,long)",
"Arrays": "java.base/java/util/Arrays.html",
"Arrays.asList()": "java.base/java/util/Arrays.html#asList(T...)",
@@ -237,10 +237,6 @@
"Math.toRadians(double)": "java.base/java/lang/Math.html#toRadians(double)",
"Math": "java.base/java/lang/Math.html",
- "Collections.sort(List)": "java.base/java/util/Collections.html#sort(java.util.List)",
- "Collections.sort(List,comparator)": "java.base/java/util/Collections.html#sort(java.util.List,java.util.Comparator)",
- "Collections.emptyList()": "java.base/java/util/Collections.html#emptyList()",
-
"File": "java.base/java/io/File.html",
"File(String)": "java.base/java/io/File.html#%3Cinit%3E(java.lang.String)",
"File(String,String)" : "java.base/java/io/File.html#%3Cinit%3E(java.lang.String,java.lang.String)",
@@ -275,6 +271,7 @@
"File.toURI()" : "java.base/java/io/File.html#toURI()",
"File.isHidden()" : "java.base/java/io/File.html#isHidden()",
"File.list()" : "java.base/java/io/File.html#list()",
+ "File.listFiles()" : "java.base/java/io/File.html#listFiles()",
"File.mkdir()" : "java.base/java/io/File.html#mkdir()",
"File.mkdirs()" : "java.base/java/io/File.html#mkdirs()",
"File.listRoots()" : "java.base/java/io/File.html#listRoots()",
@@ -314,6 +311,8 @@
"Files.readAllLines(Path)": "java.base/java/nio/file/Files.html#readAllLines(java.nio.file.Path)",
"Files.readAllLines(Path,Charset)": "java.base/java/nio/file/Files.html#readAllLines(java.nio.file.Path,java.nio.charset.Charset)",
"Files.write(byte)": "java.base/java/nio/file/Files.html#write(java.nio.file.Path,byte%5B%5D,java.nio.file.OpenOption...)",
+ "Files.writeString()": "java.base/java/nio/file/Files.html#writeString(java.nio.file.Path,java.lang.CharSequence,java.nio.file.OpenOption...)",
+ "Files.write()": "java.base/java/nio/file/Files.html#write(java.nio.file.Path,byte%5B%5D,java.nio.file.OpenOption...)",
"Files.write(Iterable)": "java.base/java/nio/file/Files.html#write(java.nio.file.Path,java.lang.Iterable,java.nio.charset.Charset,java.nio.file.OpenOption...)",
"Files.newBufferedReader(CharSet)": "java.base/java/nio/file/Files.html#newBufferedReader(java.nio.file.Path,java.nio.charset.Charset)",
"Files.newBufferedWriter()": "java.base/java/nio/file/Files.html#newBufferedWriter(java.nio.file.Path,java.nio.charset.Charset,java.nio.file.OpenOption...)",
@@ -335,9 +334,16 @@
"Files.readSymbolicLink(Path)": "java.base/java/nio/file/Files.html#readSymbolicLink(java.nio.file.Path)",
"Files.probeContentType(Path)": "java.base/java/nio/file/Files.html#probeContentType(java.nio.file.Path)",
"Files.lines(Path)": "java.base/java/nio/file/Files.html#lines(java.nio.file.Path)",
+ "Files.list(Path)": "java.base/java/nio/file/Files.html#list(java.nio.file.Path)",
+ "Files.find(Path)": "java.base/java/nio/file/Files.html#find(java.nio.file.Path,int,java.util.function.BiPredicate,java.nio.file.FileVisitOption...)",
+ "Files.walk(Path)": "java.base/java/nio/file/Files.html#walk(java.nio.file.Path,java.nio.file.FileVisitOption...)",
+ "Files.walk(Path,depth)": "java.base/java/nio/file/Files.html#walk(java.nio.file.Path,int,java.nio.file.FileVisitOption...)",
+ "Files.walkFileTree(Path)": "java.base/java/nio/file/Files.html#walkFileTree(java.nio.file.Path,java.nio.file.FileVisitor)",
"Files.copy(InputStream,Path,CopyOption)": "java.base/java/nio/file/Files.html#copy(java.io.InputStream,java.nio.file.Path,java.nio.file.CopyOption...)",
"Files.copy(Path,OutputStream)": "java.base/java/nio/file/Files.html#copy(java.nio.file.Path,java.io.OutputStream)",
"Files.copy(Path,Path,CopyOption)": "java.base/java/nio/file/Files.html#copy(java.nio.file.Path,java.nio.file.Path,java.nio.file.CopyOption...)",
+ "Files.readString(Path)": "java.base/java/nio/file/Files.html#readString(java.nio.file.Path)",
+ "Files.readAllBytes(Path)": "java.base/java/nio/file/Files.html#readAllBytes(java.nio.file.Path)",
"Files.setAttribute(Path,String,Object,LinkOption)": "java.base/java/nio/file/Files.html#setAttribute(java.nio.file.Path,java.lang.String,java.lang.Object,java.nio.file.LinkOption...)",
"Files.createTempFile(String,String,FileAttribute)": "java.base/java/nio/file/Files.html#createTempFile(java.lang.String,java.lang.String,java.nio.file.attribute.FileAttribute...)",
"Files.createTempFile(Path,String,String,FileAttribute)": "java.base/java/nio/file/Files.html#createTempFile(java.nio.file.Path,java.lang.String,java.lang.String,java.nio.file.attribute.FileAttribute...)",
@@ -407,9 +413,7 @@
"FileTime": "java.base/java/nio/file/attribute/FileTime.html",
- "Iterable": "java.base/java/lang/Iterable.html",
- "Iterable.forEach()": "java.base/java/lang/Iterable.html#forEach(java.util.function.Consumer)",
- "Iterable.iterator()": "java.base/java/lang/Iterable.html#iterator()",
+ "Console": "java.base/java/io/Console.html",
"Path": "java.base/java/nio/file/Path.html",
"Path.toFile()": "java.base/java/nio/file/Path.html#toFile()",
@@ -451,6 +455,8 @@
"Float.parseFloat(String)": "java.base/java/lang/Float.html#parseFloat(java.lang.String)",
"Double": "java.base/java/lang/Double.html",
+ "Double.toString(double)": "java.base/java/lang/Double.html#Double.html#toString(double)",
+ "Double.parseDouble(String)": "java.base/java/lang/Double.html#parseDouble(java.lang.String)",
"Double.compareTo(Double)": "java.base/java/lang/Double.html#compareTo(java.lang.Double)",
"Character": "java.base/java/lang/Character.html",
@@ -504,7 +510,8 @@
"String.regionMatches(int,String,int,int)": "java.base/java/lang/String.html#regionMatches(int,java.lang.String,int,int)",
"String.equals(Object)": "java.base/java/lang/String.html#equals(java.lang.Object)",
"String.regionMatches(boolean,int,String,int,int)": "java.base/java/lang/String.html#regionMatches(boolean,int,java.lang.String,int,int)",
- "String.join(CharSequence,CharSequence)": "java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.CharSequence)",
+ "String.join(CharSequence,CharSequence)": "java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.CharSequence...)",
+ "String.join(CharSequence,Iterable)": "java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.Iterable)",
"String.valueOf(Object)": "java.base/java/lang/String.html#valueOf(java.lang.Object)",
"StringIndexOutOfBoundsException": "java.base/java/lang/StringIndexOutOfBoundsException.html",
@@ -514,8 +521,8 @@
"StringBuilder": "java.base/java/lang/StringBuilder.html",
"StringBuilder()": "java.base/java/lang/StringBuilder.html#%3Cinit%3E()",
- "StringBuilder(CharSequence)": "java/lang/StringBuilder.html#%3Cinit%3E(java.lang.CharSequence)",
- "StringBuilder(String)": "java/lang/StringBuilder.html#%3Cinit%3E(java.lang.String)",
+ "StringBuilder(CharSequence)": "java.base/java/lang/StringBuilder.html#%3Cinit%3E(java.lang.CharSequence)",
+ "StringBuilder(String)": "java.base/java/lang/StringBuilder.html#%3Cinit%3E(java.lang.String)",
"StringBuilder(int)": "java.base/java/lang/StringBuilder.html#%3Cinit%3E(int)",
"StringBuilder.length()": "java.base/java/lang/StringBuilder.html#length()",
"StringBuilder.capacity()": "java.base/java/lang/StringBuilder.html#capacity()",
@@ -556,6 +563,7 @@
"Externalizable": "java.base/java/io/Externalizable.html",
"Writer": "java.base/java/io/Writer.html",
+ "FileWriter": "java.base/java/io/FileWriter.html",
"FileReader": "java.base/java/io/FileReader.html",
"FilterWriter": "java.base/java/io/FilterWriter.html",
"CharArrayReader": "java.base/java/io/CharArrayReader.html",
@@ -567,6 +575,7 @@
"LineNumberReader": "java.base/java/io/LineNumberReader.html",
"BufferedWriter": "java.base/java/io/BufferedWriter.html",
+ "BufferedWriter.write(int)": "java.base/java/io/BufferedWriter.html#write(int)",
"BufferedWriter.close()": "java.base/java/io/BufferedWriter.html#close()",
"FileNotFoundException": "java.base/java/io/FileNotFoundException.html",
@@ -602,10 +611,14 @@
"BufferedOutputStream": "java.base/java/io/BufferedOutputStream.html",
"PrintWriter": "java.base/java/io/PrintWriter.html",
+ "PrintWriter.printf()": "java.base/java/io/PrintWriter.html#printf(java.lang.String,java.lang.Object...)",
"PrintWriter.println()": "java.base/java/io/PrintWriter.html#println()",
- "GZIPInputStream": "java.base/java/io/GZIPInputStream.html",
- "GZIPOutputStream": "java.base/java/io/GZIPOutputStream.html",
+ "ZipInputStream": "java.base/java/util/zip/ZipInputStream.html",
+ "ZipOutputStream": "java.base/java/util/zip/ZipOutputStream.html",
+
+ "GZIPInputStream": "java.base/java/util/zip/GZIPInputStream.html",
+ "GZIPOutputStream": "java.base/java/util/zip/GZIPOutputStream.html",
"DataOutputStream": "java.base/java/io/DataOutputStream.html",
"DataOutputStream.writeBoolean(boolean)": "java.base/java/io/DataOutputStream#writeBoolean(boolean)",
@@ -642,6 +655,8 @@
"InputStreamReader": "java.base/java/io/InputStreamReader.html",
"OutputStreamWriter": "java.base/java/io/OutputStreamWriter.html",
+ "Scanner": "java.base/java/util/Scanner.html",
+
"Closeable": "java.base/java/io/Closeable.html",
"Closeable.close()": "java.base/java/io/Closeable.html#close()",
@@ -671,6 +686,8 @@
"SeekableByteChannel.write(ByteBuffer)": "java.base/java/nio/channels/SeekableByteChannel.html#write(java.nio.ByteBuffer)",
"SeekableByteChannel.truncate(long)": "java.base/java/nio/channels/SeekableByteChannel.html#truncate(long)",
+ "ImageIO.read(URL)": "java.desktop/javax/imageio/ImageIO.html#read(java.net.URL)",
+
"URI": "java.base/java/net/URI.html",
"LinkedList": "java.base/java/util/LinkedList.html",
@@ -918,7 +935,8 @@
"TimeZone.toZoneId()": "java.base/java/util/TimeZone.html#toZoneId()",
"DateTimeParseException": "java.base/java/time/format/DateTimeParseException.html",
- "DateTimeException": "java.base/java/time/format/DateTimeException.html",
+
+ "DateTimeException": "java.base/java/time/DateTimeException.html",
"DecimalFormat": "java.base/java/text/DecimalFormat.html",
@@ -950,6 +968,7 @@
"NegativeArraySizeException": "java.base/java/lang/NegativeArraySizeException.html",
"EmptyStackException": "java.base/java/util/EmptyStackException.html",
"RuntimeException": "java.base/java/lang/RuntimeException.html",
+ "ReflectiveOperationException": "java.base/java/lang/ReflectiveOperationException.html",
"ArrayStoreException": "java.base/java/lang/ArrayStoreException.html",
"ClassCastException": "java.base/java/lang/ClassCastException.html",
@@ -1043,9 +1062,6 @@
"RetentionPolicy.RUNTIME": "java.base/java/lang/annotation/RetentionPolicy.html#RUNTIME",
"RetentionPolicy.SOURCE": "java.base/java/lang/annotation/RetentionPolicy.html#SOURCE",
"Target": "java.base/java/lang/annotation/Target.html",
- "AnnotatedElement": "java.base/java/lang/reflect/AnnotatedElement.html",
- "AnnotatedElement.getAnnotation(Class)": "java.base/java/lang/reflect/AnnotatedElement.html#getAnnotation(java.lang.Class)",
- "AnnotatedElement.getAnnotationsByType(Class)": "java.base/java/lang/reflect/AnnotatedElement.html#getAnnotationsByType(java.lang.Class)",
"IllegalArgumentException": "java.base/java/lang/IllegalArgumentException.html",
"IllegalStateException": "java.base/java/lang/IllegalStateException.html",
@@ -1055,9 +1071,20 @@
"ArrayDeque": "java.base/java/util/ArrayDeque.html",
+ "Iterator": "java.base/java/util/Iterator.html",
+ "Iterator.hasNext()": "java.base/java/util/Iterator.html#hasNext()",
+ "Iterator.next()": "java.base/java/util/Iterator.html#next()",
+ "Iterator.remove()": "java.base/java/util/Iterator.html#remove()",
+ "Iterator.forEachRemaining(Consumer)": "java.base/java/util/Iterator.html#forEachRemaining(java.util.function.Consumer)",
+
+ "Iterable": "java.base/java/lang/Iterable.html",
+ "Iterable.forEach()": "java.base/java/lang/Iterable.html#forEach(java.util.function.Consumer)",
+ "Iterable.iterator()": "java.base/java/lang/Iterable.html#iterator()",
+
"Collection": "java.base/java/util/Collection.html",
"Collection.removeIf(Predicate)": "java.base/java/util/Collection.html#removeIf(java.util.function.Predicate)",
"Collection.add(E)": "java.base/java/util/Collection.html#add(E)",
+ "Collection.remove(Object)": "java.base/java/util/Collection.html#remove(java.lang.Object)",
"Collection.addAll(Collection)": "java.base/java/util/Collection.html#addAll(java.util.Collection)",
"Collection.clear()": "java.base/java/util/Collection.html#clear()",
"Collection.contains(Object)": "java.base/java/util/Collection.html#contains(java.lang.Object)",
@@ -1079,8 +1106,11 @@
"Collections.min(Collection)": "java.base/java/util/Collections.html#min(java.util.Collection)",
"Collections.reverse(List)": "java.base/java/util/Collections.html#reverse(java.util.List)",
"Collections.rotate(List,int)": "java.base/java/util/Collections.html#rotate(java.util.List,int)",
- "Collections.shuffle(List)": "java.base/java/util/Collections.html#shuffle(java.util.List)",
"Collections.swap(List,int,int)": "java.base/java/util/Collections.html#swap(java.util.List,int,int)",
+ "Collections.sort(List)": "java.base/java/util/Collections.html#sort(java.util.List)",
+ "Collections.shuffle(List)": "java.base/java/util/Collections.html#shuffle(java.util.List)",
+ "Collections.sort(List,comparator)": "java.base/java/util/Collections.html#sort(java.util.List,java.util.Comparator)",
+ "Collections.emptyList()": "java.base/java/util/Collections.html#emptyList()",
"Deque": "java.base/java/util/Deque.html",
"Deque.addFirst(E)": "java.base/java/util/Deque.html#addFirst(E)",
@@ -1108,11 +1138,6 @@
"IdentityHashMap": "java.base/java/util/IdentityHashMap.html",
- "Iterator": "java.base/java/util/Iterator.html",
- "Iterator.hasNext()": "java.base/java/util/Iterator.html#hasNext()",
- "Iterator.next()": "java.base/java/util/Iterator.html#next()",
- "Iterator.remove()": "java.base/java/util/Iterator.html#remove()",
-
"LinkedHashMap": "java.base/java/util/LinkedHashMap.html",
"List": "java.base/java/util/List.html",
@@ -1193,6 +1218,9 @@
"NavigableMap.subMap(K,boolean,K,boolean)": "java.base/java/util/NavigableMap.html#subMap(K,boolean,K,boolean)",
"NavigableMap.tailMap(K)": "java.base/java/util/NavigableMap.html#tailMap(K)",
+ "ConcurrentMap": "java.base/java/util/concurrent/ConcurrentMap.html",
+ "ConcurrentMap.putIfAbsent()": "java.base/java/util/concurrent/ConcurrentMap.html#putIfAbsent()",
+
"NavigableSet": "java.base/java/util/NavigableSet.html",
"NavigableSet.ceiling(E)": "java.base/java/util/NavigableSet.html#ceiling(E)",
"NavigableSet.descendingIterator()": "java.base/java/util/NavigableSet.html#descendingIterator()",
@@ -1256,6 +1284,7 @@
"NumberFormatException": "java.base/java/lang/NumberFormatException.html",
"OutOfMemoryError": "java.base/java/lang/OutOfMemoryError.html",
+ "Character.UnicodeBlock": "java.base/java/lang/Character.UnicodeBlock.html",
"Character.toString(int)": "java.base/java/lang/Character.html#toString(int)",
"Charset": "java.base/java/nio/charset/Charset.html",
@@ -1392,6 +1421,7 @@
"Stream.toArray()": "java.base/java/util/stream/Stream.html#toArray()",
"Stream.toList()": "java.base/java/util/stream/Stream.html#toList()",
+ "HttpClient": "java.net.http/java/net/http/HttpClient.html",
"HttpClient.send(HttpRequest,HttpResponse.BodyHandler)": "java.net.http/java/net/http/HttpClient.html#send(java.net.http.HttpRequest,java.net.http.HttpResponse.BodyHandler)",
"HttpResponse.BodyHandlers.ofLines()": "java.net.http/java/net/http/HttpResponse.BodyHandlers.html#ofLines()",
@@ -1408,10 +1438,15 @@
"Security.getProviders()": "java.base/java/security/Security.html#getProviders()",
"Security.addProvider(java.security.Provider)": "java.base/java/security/Security.html#addProvider(java.security.Provider)",
"Security.insertProviderAt": "java.base/java/security/Security.html#insertProviderAt(java.security.Provider,int)",
+ "Certificate": "java.base/java/security/cert/Certificate.html",
+ "X509Certificate": "java.base/java/security/cert/X509Certificate.html",
+ "TrustAnchor": "java.base/java/security/cert/TrustAnchor.html",
+ "CertPathValidator": "java.base/java/security/cert/CertPathValidator.html",
+ "Security": "java.base/java/security/Security.html",
+ "FlightRecorderMXBean": "jdk.management.jfr/jdk/management/jfr/FlightRecorderMXBean.html",
+ "MBeanServerConnection": "java.management/javax/management/MBeanServerConnection.html",
+ "SimpleFileServer": "jdk.httpserver/com/sun/net/httpserver/SimpleFileServer",
- "Method": "java.base/java/lang/reflect/Method.html",
- "Field": "java.base/java/lang/reflect/Field.html",
- "Member": "java.base/java/lang/reflect/Member.html",
"Lookup": "java.base/java/lang/invoke/MethodHandles.Lookup.html",
"MethodType": "java.base/java/lang/invoke/MethodType.html",
"MethodHandles": "java.base/java/lang/invoke/MethodHandles.html",
@@ -1442,5 +1477,127 @@
"MethodHandle.invokeWithArguments(Object...)": "java.base/java/lang/invoke/MethodHandle.html#invokeWithArguments(java.lang.Object...)",
"MethodHandle.asType(MethodType)": "java.base/java/lang/invoke/MethodHandle.html#asType(java.lang.invoke.MethodType)",
"VarHandle": "java.base/java/lang/invoke/VarHandle.html",
- "WrongMethodTypeException": "java.base/java/lang/invoke/WrongMethodTypeException.html"
+ "WrongMethodTypeException": "java.base/java/lang/invoke/WrongMethodTypeException.html",
+
+ "ReflectPermission": "java.base/java/lang/reflect/ReflectPermission.html",
+
+ "java.lang.reflect": "java.base/java/lang/reflect/package-summary.html",
+
+ "Class": "java.base/java/lang/Class.html",
+ "Class.getFields()": "java.base/java/lang/Class.html#getFields()",
+ "Class.getInterfaces()": "java.base/java/lang/Class.html#getInterfaces()",
+ "Class.getMethods()": "java.base/java/lang/Class.html#getMethods()",
+ "Class.getSimpleName()": "java.base/java/lang/Class.html#getSimpleName()",
+ "Class.getSuperclass()": "java.base/java/lang/Class.html#getSuperclass()",
+ "Class.isAnnotation()": "java.base/java/lang/Class.html#isAnnotation()",
+ "Class.isEnum()": "java.base/java/lang/Class.html#isEnum()",
+ "Class.isInterface()": "java.base/java/lang/Class.html#isInterface()",
+ "Class.toString()": "java.base/java/lang/Class.html#toString()",
+ "Class.forName(String)": "java.base/java/lang/Class.html#forName(java.lang.String)",
+ "Class.getName()": "java.base/java/lang/Class.html#getName()",
+ "Class.getCanonicalName()": "java.base/java/lang/Class.html#getCanonicalName()",
+ "Class.getTypeName()": "java.base/java/lang/Class.html#getTypeName()",
+ "Class.forPrimitiveName()": "java.base/java/lang/Class.html#forPrimitiveName()",
+ "Class.getClasses()": "java.base/java/lang/Class.html#getClasses()",
+ "Class.getEnclosingClass()": "java.base/java/lang/Class.html#getEnclosingClass()",
+ "Class.getDeclaredClasses()": "java.base/java/lang/Class.html#getDeclaredClasses()",
+ "Class.getDeclaringClass()": "java.base/java/lang/Class.html#getDeclaringClass()",
+ "Class.getModifiers()": "java.base/java/lang/Class.html#getModifiers()",
+ "Class.getDeclaredField(String)": "java.base/java/lang/Class.html#getDeclaredField(java.lang.String)",
+ "Class.getField(String)": "java.base/java/lang/Class.html#getField(java.lang.String)",
+ "Class.getDeclaredFields()": "java.base/java/lang/Class.html#getDeclaredFields()",
+ "Class.getDeclaredMethod(String,Class...)": "java.base/java/lang/Class.html#getDeclaredMethod(java.lang.String,java.lang.Class...)",
+ "Class.getMethod(String,Class...)": "java.base/java/lang/Class.html#getMethod(java.lang.String,java.lang.Class...)",
+ "Class.getDeclaredMethods()": "java.base/java/lang/Class.html#getDeclaredMethods()",
+ "Class.getDeclaredConstructor(Class...)": "java.base/java/lang/Class.html#getDeclaredConstructor(java.lang.Class...)",
+ "Class.getConstructor(Class...)": "java.base/java/lang/Class.html#getConstructor(java.lang.Class...)",
+ "Class.getDeclaredConstructors()": "java.base/java/lang/Class.html#getDeclaredConstructors()",
+ "Class.getConstructors()": "java.base/java/lang/Class.html#getConstructors()",
+ "Class.newInstance()": "java.base/java/lang/Class.html#newInstance()",
+ "Class.isRecord()": "java.base/java/lang/Class.html#isRecord()",
+ "Class.getEnumConstants()": "java.base/java/lang/Class.html#getEnumConstants()",
+ "Class.isArray()": "java.base/java/lang/Class.html#isArray()",
+ "Class.getComponentType()": "java.base/java/lang/Class.html#getComponentType()",
+
+ "Void": "java.base/java/lang/Void.html",
+ "Void.TYPE": "java.base/java/lang/Void.html#TYPE",
+
+ "Type": "java.base/java/lang/reflect/Type.html",
+ "Type.getTypeName()": "java.base/java/lang/reflect/Type.html#getTypeName()",
+
+ "Member": "java.base/java/lang/reflect/Member.html",
+ "Member.accessFlags()": "java.base/java/lang/reflect/Member.html#accessFlags()",
+ "Member.getDeclaringClass()": "java.base/java/lang/reflect/Member.html#getDeclaringClass()",
+
+ "Field": "java.base/java/lang/reflect/Field.html",
+ "Field.getFields()": "java.base/java/lang/reflect/Field.html#getFields()",
+ "Field.getType()": "java.base/java/lang/reflect/Field.html#getType()",
+ "Field.getGenericType()": "java.base/java/lang/reflect/Field.html#getGenericType()",
+ "Field.getModifiers()": "java.base/java/lang/reflect/Field.html#getModifiers()",
+ "Field.accessFlags()": "java.base/java/lang/reflect/Field.html#accessFlags()",
+ "Field.get(Object)": "java.base/java/lang/reflect/Field.html#get(java.lang.Object)",
+ "Field.set(Object,Object)": "java.base/java/lang/reflect/Field.html#set(java.lang.Object,java.lang.Object)",
+ "Field.setInt(Object,int)": "java.base/java/lang/reflect/Field.html#setInt(java.lang.Object,int)",
+ "Field.getInt(Object)": "java.base/java/lang/reflect/Field.html#getInt(java.lang.Object)",
+ "Field.setAccessible()": "java.base/java/lang/reflect/Field.html#setAccessible()",
+ "Field.isEnumConstant()": "java.base/java/lang/reflect/Field.html#isEnumConstant()",
+
+ "Method": "java.base/java/lang/reflect/Method.html",
+ "Method.invoke(Object,Object...)": "java.base/java/lang/reflect/Method.html#invoke(java.lang.Object,java.lang.Object...)",
+ "Method.invoke()": "java.base/java/lang/reflect/Method.html#invoke()",
+ "Method.getReturnType()": "java.base/java/lang/reflect/Method.html#getReturnType()",
+ "Method.getGenericReturnType()": "java.base/java/lang/reflect/Method.html#getGenericReturnType()",
+ "Method.getGenericExceptionTypes()": "java.base/java/lang/reflect/Method.html#getGenericExceptionTypes()",
+ "Method.getModifiers()": "java.base/java/lang/reflect/Method.html#getModifiers()",
+ "Method.setAccessible(boolean)": "java.base/java/lang/reflect/Method.html#setAccessible(boolean)",
+
+ "Constructor": "java.base/java/lang/reflect/Constructor.html",
+ "Constructor.newInstance()": "java.base/java/lang/reflect/Constructor.html#newInstance()",
+ "Constructor.getParameterTypes()": "java.base/java/lang/reflect/Constructor.html#getParameterTypes()",
+ "Constructor.getGenericParameterTypes()": "java.base/java/lang/reflect/Constructor.html#getGenericParameterTypes()",
+
+ "RecordComponent": "java.base/java/lang/reflect/RecordComponent.html",
+ "RecordComponent.getDeclaringRecord()": "java.base/java/lang/reflect/RecordComponent.html#getDeclaringRecord()",
+ "RecordComponent.getAccessor()": "java.base/java/lang/reflect/RecordComponent.html#getAccessor()",
+ "RecordComponent.getName()": "java.base/java/lang/reflect/RecordComponent.html#getName()",
+ "RecordComponent.getType()": "java.base/java/lang/reflect/RecordComponent.html#getType()",
+ "RecordComponent.getGenericType()": "java.base/java/lang/reflect/RecordComponent.html#getGenericType()",
+
+ "Array": "java.base/java/lang/reflect/Array.html",
+ "Array.newInstance()": "java.base/java/lang/reflect/Array.html#newInstance()",
+ "Array.newInstance(Class,int)": "java.base/java/lang/reflect/Array.html#newInstance(java.lang.Class,int)",
+ "Array.getLength(Object)": "java.base/java/lang/reflect/Array.html#getLength(java.lang.Object)",
+ "Array.set(Object,int,Object)": "java.base/java/lang/reflect/Array.html#set(java.lang.Object,int,java.lang.Object)",
+ "Array.get(Object,int)": "java.base/java/lang/reflect/Array.html#set(java.lang.Object,int)",
+ "Array.setDouble(Object,int,double)": "java.base/java/lang/reflect/Array.html#setDouble(java.lang.Object,int,double)",
+ "Array.getDouble(Object,int)": "java.base/java/lang/reflect/Array.html#getDouble(java.lang.Object,int)",
+
+ "AnnotatedElement": "java.base/java/lang/reflect/AnnotatedElement.html",
+ "AnnotatedElement.getDeclaredAnnotations()": "java.base/java/lang/reflect/AnnotatedElement.html#getDeclaredAnnotations()",
+ "AnnotatedElement.getAnnotations()": "java.base/java/lang/reflect/AnnotatedElement.html#getAnnotations()",
+ "AnnotatedElement.isAnnotationPresent(Class)": "java.base/java/lang/reflect/AnnotatedElement.html#isAnnotationPresent(java.lang.Class)",
+ "AnnotatedElement.getAnnotation(Class)": "java.base/java/lang/reflect/AnnotatedElement.html#getAnnotation(java.lang.Class)",
+ "AnnotatedElement.getDeclaredAnnotation(Class)": "java.base/java/lang/reflect/AnnotatedElement.html#getDeclaredAnnotation(java.lang.Class)",
+ "AnnotatedElement.getAnnotationsByType(Class)": "java.base/java/lang/reflect/AnnotatedElement.html#getAnnotationsByType(java.lang.Class)",
+
+ "AnnotatedType": "java.base/java/lang/reflect/AnnotatedType.html",
+
+ "Proxy": "java.base/java/lang/reflect/Proxy.html",
+
+ "Executable": "java.base/java/lang/reflect/Executable.html",
+ "Executable.getParameters()": "java.base/java/lang/reflect/Executable.html#getParameters()",
+
+ "AccessFlag": "java.base/java/lang/reflect/AccessFlag.html",
+
+ "Modifier": "java.base/java/lang/reflect/Modifier.html",
+
+ "ClassNotFoundException": "java.base/java/lang/ClassNotFoundException.html",
+ "InstantiationException": "java.base/java/lang/InstantiationException.html",
+ "InvocationTargetException": "java.base/java/lang/reflect/InvocationTargetException.html",
+ "InvocationTargetException.getTargetException()": "java.base/java/lang/reflect/InvocationTargetException.html#getTargetException()",
+
+ "jdk.jshell": "jdk.jshell/module-summary.html",
+
+ "jdeps-man": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jdeps.html#options-to-filter-classes-to-be-analyzed",
+ "jlink-man": "https://docs.oracle.com/en/java/javase/@@CURRENT_RELEASE@@/docs/specs/man/jlink.html"
}
\ No newline at end of file
diff --git a/app/data/javafxdoc.json b/app/data/javafxdoc.json
index ec8ef57..dfc5f19 100644
--- a/app/data/javafxdoc.json
+++ b/app/data/javafxdoc.json
@@ -1,8 +1,8 @@
{
- "current_release": "19",
+ "current_release": "23",
+ "release_uuid": "343fae14109c42b09c0437fc90a10d4b",
- "javafx-documentation": "https://openjfx.io/javadoc/@@CURRENT_RELEASE@@/",
- "javafxdoc_root": "https://openjfx.io/javadoc/@@CURRENT_RELEASE@@/",
+ "javafxdoc_root": "https://download.java.net/java/GA/javafx@@CURRENT_RELEASE@@/@@RELEASE_UUID@@/docs/api/",
"Application": "javafx.graphics/javafx/application/Application.html",
@@ -54,28 +54,27 @@
"FXMLLoader": "javafx.fxml/javafx/fxml/FXMLLoader.html",
"Initializable": "javafx.fxml/javafx/fxml/Initializable.html",
-
- "AnimationPackageSummary": "javafx.graphics/javafx/animation/package-summary",
- "WritableValue": "javafx.base/javafx/beans/value/WritableValue",
- "Animation": "javafx.graphics/javafx/animation/Animation",
- "Duration": "javafx.base/javafx/util/Duration",
- "Node": "javafx.graphics/javafx/scene/Node",
- "FadeTransition": "javafx.graphics/javafx/animation/FadeTransition",
- "FillTransition": "javafx.graphics/javafx/animation/FillTransition",
- "PathTransition": "javafx.graphics/javafx/animation/PathTransition",
- "ScaleTransition": "javafx.graphics/javafx/animation/ScaleTransition",
- "StrokeTransition": "javafx.graphics/javafx/animation/StrokeTransition",
- "TranslateTransition": "javafx.graphics/javafx/animation/TranslateTransition",
- "Timeline": "javafx.graphics/javafx/animation/Timeline",
- "KeyFrame": "javafx.graphics/javafx/animation/KeyFrame",
- "KeyValue": "javafx.graphics/javafx/animation/KeyValue",
- "Interpolator": "javafx.graphics/javafx/animation/Interpolator",
- "Interpolator.DISCRETE": "javafx.graphics/javafx/animation/Interpolator#DISCRETE",
- "Interpolator.LINEAR": "javafx.graphics/javafx/animation/Interpolator#LINEAR",
- "Interpolator.EASE_IN": "javafx.graphics/javafx/animation/Interpolator#EASE_IN",
- "Interpolator.EASE_OUT": "javafx.graphics/javafx/animation/Interpolator#EASE_OUT",
- "Interpolator.EASE_BOTH": "javafx.graphics/javafx/animation/Interpolator#EASE_BOTH",
- "Interpolator.SPLINE": "javafx.graphics/javafx/animation/Interpolator#SPLINE(double,double,double,double)",
- "Interpolator.TANGENT": "javafx.graphics/javafx/animation/Interpolator#TANGENT(javafx.util.Duration,double,javafx.util.Duration,double)",
- "AnimationTimer": "javafx.graphics/javafx/animation/AnimationTimer"
-}
+ "AnimationPackageSummary": "javafx.graphics/javafx/animation/package-summary.html",
+ "WritableValue": "javafx.base/javafx/beans/value/WritableValue.html",
+ "Animation": "javafx.graphics/javafx/animation/Animation.html",
+ "Duration": "javafx.base/javafx/util/Duration.html",
+ "Node": "javafx.graphics/javafx/scene/Node.html",
+ "FadeTransition": "javafx.graphics/javafx/animation/FadeTransition.html",
+ "FillTransition": "javafx.graphics/javafx/animation/FillTransition.html",
+ "PathTransition": "javafx.graphics/javafx/animation/PathTransition.html",
+ "ScaleTransition": "javafx.graphics/javafx/animation/ScaleTransition.html",
+ "StrokeTransition": "javafx.graphics/javafx/animation/StrokeTransition.html",
+ "TranslateTransition": "javafx.graphics/javafx/animation/TranslateTransition.html",
+ "Timeline": "javafx.graphics/javafx/animation/Timeline.html",
+ "KeyFrame": "javafx.graphics/javafx/animation/KeyFrame.html",
+ "KeyValue": "javafx.graphics/javafx/animation/KeyValue.html",
+ "Interpolator": "javafx.graphics/javafx/animation/Interpolator.html",
+ "Interpolator.DISCRETE": "javafx.graphics/javafx/animation/Interpolator.html#DISCRETE",
+ "Interpolator.LINEAR": "javafx.graphics/javafx/animation/Interpolator.html#LINEAR",
+ "Interpolator.EASE_IN": "javafx.graphics/javafx/animation/Interpolator.html#EASE_IN",
+ "Interpolator.EASE_OUT": "javafx.graphics/javafx/animation/Interpolator.html#EASE_OUT",
+ "Interpolator.EASE_BOTH": "javafx.graphics/javafx/animation/Interpolator.html#EASE_BOTH",
+ "Interpolator.SPLINE": "javafx.graphics/javafx/animation/Interpolator.html#SPLINE(double,double,double,double)",
+ "Interpolator.TANGENT": "javafx.graphics/javafx/animation/Interpolator.html#TANGENT(javafx.util.Duration,double,javafx.util.Duration,double)",
+ "AnimationTimer": "javafx.graphics/javafx/animation/AnimationTimer.html"
+}
\ No newline at end of file
diff --git a/app/data/jep.json b/app/data/jep.json
new file mode 100644
index 0000000..80bcff7
--- /dev/null
+++ b/app/data/jep.json
@@ -0,0 +1,73 @@
+{
+ "root": "https://openjdk.org/jeps/",
+
+ "1": "JDK Enhancement-Proposal & Roadmap Process",
+ "11": "Incubator Modules",
+ "12": "Preview Features",
+
+ "110": "HTTP/2 Client (Incubator)",
+
+ "220": "Modular Run-Time Images",
+ "225": "Javadoc Search",
+ "286": "Local-Variable Type Inference",
+
+ "310": "Application Class-Data Sharing",
+ "321": "HTTP Client",
+ "325": "Switch Expressions (Preview)",
+ "326": "Raw String Literals (Preview)",
+ "328": "Flight Recorder",
+ "333": "ZGC: A Scalable Low-Latency Garbage Collector (Experimental)",
+ "345": "NUMA-Aware Memory Allocation for G1",
+ "346": "Promptly Return Unused Committed Memory from G1",
+ "349": "JFR Event Streaming",
+ "354": "Switch Expressions (Second Preview)",
+ "357": "Migrate from Mercurial to Git",
+ "358": "Helpful NullPointerExceptions",
+ "361": "Switch Expressions",
+ "363": "Remove the Concurrent Mark Sweep (CMS) Garbage Collector",
+ "369": "Migrate to GitHub",
+ "372": "Remove the Nashorn JavaScript Engine",
+ "374": "Disable and Deprecate Biased Locking",
+ "376": "ZGC: Concurrent Thread-Stack Processing",
+ "377": "ZGC: A Scalable Low-Latency Garbage Collector (Production)",
+ "384": "Records (Second Preview)",
+ "387": "Elastic Metaspace",
+ "391": "macOS/AArch64 Port",
+ "395": "Records",
+ "397": "Sealed Classes (Second Preview)",
+ "398": "Deprecate the Applet for Removal",
+
+ "400": "UTF-8 by Default",
+ "407": "Remove RMI Activation",
+ "408": "Simple Web Server",
+ "409": "Sealed Classes",
+ "411": "Deprecate the Security Manager for Removal",
+ "413": "Code Snippets in Java API Documentation",
+ "415": "Context-Specific Deserialization Filters",
+ "416": "Reimplement Core Reflection with Method Handle",
+ "418": "Internet-Address Resolution API",
+ "421": "Deprecate Finalization for Removal",
+ "445": {
+ "title": "Implicitly Declared Classes and Instance Main Methods (Second Preview)",
+ "status": "preview",
+ "version": "22"
+ },
+ "460": {
+ "title": "Vector API (Seventh Incubator)",
+ "status": "incubator",
+ "version": "22"
+ },
+ "463": {
+ "title": "Implicitly Declared Classes and Instance Main Methods (Second Preview)",
+ "status": "preview",
+ "version": "22"
+ },
+
+ "481": {
+ "title": "Scoped Values (Third Preview)",
+ "status": "preview",
+ "version": "22"
+ },
+
+ "8300604": "JEP draft: Preview Features: A Look Back, and A Look Ahead"
+}
\ No newline at end of file
diff --git a/app/pages/future/innovation/index.md b/app/pages/future/innovation/index.md
index e86051e..8825b54 100644
--- a/app/pages/future/innovation/index.md
+++ b/app/pages/future/innovation/index.md
@@ -7,11 +7,11 @@ subheader_select: innovation
## Amber
-The goal of Project Amber is to explore and incubate smaller, productivity-oriented Java language features that have been accepted as candidate JEPs under the [OpenJDK JEP process](https://openjdk.java.net/jeps/1). This Project is sponsored by the [Compiler Group](https://openjdk.java.net/groups/compiler/).
+The goal of Project Amber is to explore and incubate smaller, productivity-oriented Java language features that have been accepted as candidate JEPs under [JDK Enhancement-Proposal & Roadmap Process](jep:1). This Project is sponsored by the [Compiler Group](https://openjdk.org/groups/compiler/).
-Most Project Amber features go through at least one round of Preview before becoming an official part of Java SE. See [JEP 12](https://openjdk.java.net/jeps/12) for an explanation of the Preview process, and [our tutorial](id:new_features.using_preview) on how to use preview features. For a given feature, there are separate JEPs for each round of preview and for final standardization.
+Most Project Amber features go through at least one round of Preview before becoming an official part of Java SE. See [Preview Features](jep:12) for an explanation of the Preview process, and [our tutorial](id:new_features.using_preview) on how to use preview features. For a given feature, there are separate JEPs for each round of preview and for final standardization.
-Learn more at Project Amber's [Wiki](https://openjdk.java.net/projects/amber/), as well as Inside.java's [Amber page](https://inside.java/tag/amber).
+Learn more at Project Amber's [Wiki](https://openjdk.org/projects/amber/), as well as Inside.java's [Amber page](https://inside.java/tag/amber).
## Loom
@@ -23,7 +23,7 @@ Project Loom is to intended to explore, incubate and deliver Java VM features an
This OpenJDK project is sponsored by the HotSpot Group.
-Learn more at Project Loom's [Wiki](https://wiki.openjdk.java.net/display/loom/Main), as well as Inside.java's [Loom page](https://inside.java/tag/loom).
+Learn more at Project Loom's [Wiki](https://wiki.openjdk.org/display/loom/Main), as well as Inside.java's [Loom page](https://inside.java/tag/loom).
## Panama
@@ -43,7 +43,7 @@ To this end, Project Panama will include most or all of these components:
* tooling or wrapper interposition for safety
* exploratory work with difficult-to-integrate native libraries
-Learn more at Project Panama's [Wiki](https://openjdk.java.net/projects/panama/), as well as Inside.java's [Panama page](https://inside.java/tag/panama).
+Learn more at Project Panama's [Wiki](https://openjdk.org/projects/panama/), as well as Inside.java's [Panama page](https://inside.java/tag/panama).
## Valhalla
@@ -58,7 +58,7 @@ The three main goals are:
A number of people describe Valhalla recently as being "primarily about performance". While it is understandable why people might come to that conclusion -- many of the motivations for Valhalla are, in fact, rooted in performance considerations -- this characterization misses something very important. Yes, performance is an important part of the story -- but so are safety, abstraction, encapsulation, expressiveness, maintainability, and compatible library evolution.
-Learn more at the Valhalla Project [Wiki](https://wiki.openjdk.java.net/display/valhalla/Main), as well as Inside.java's [Valhalla page](https://inside.java/tag/valhalla).
+Learn more at the Valhalla Project [Wiki](https://wiki.openjdk.org/display/valhalla/Main), as well as Inside.java's [Valhalla page](https://inside.java/tag/valhalla).
## ZGC
@@ -81,5 +81,5 @@ At a glance, ZGC is:
At its core, ZGC is a concurrent garbage collector, meaning all heavy lifting work is done while Java threads continue to execute. This greatly limits the impact garbage collection will have on your application's response time.
-Learn more at the ZGC [Wiki](https://wiki.openjdk.java.net/display/zgc/Main), as well as Inside.java's [GC page](https://inside.java/tag/gc).
+Learn more at the ZGC [Wiki](https://wiki.openjdk.org/display/zgc/Main), as well as Inside.java's [GC page](https://inside.java/tag/gc).
diff --git a/app/pages/learn/01_tutorial/03_getting-to-know-the-language/04_classes_objects/01_enums.md b/app/pages/learn/01_tutorial/03_getting-to-know-the-language/04_classes_objects/01_enums.md
index 651a2ea..ddfac6e 100644
--- a/app/pages/learn/01_tutorial/03_getting-to-know-the-language/04_classes_objects/01_enums.md
+++ b/app/pages/learn/01_tutorial/03_getting-to-know-the-language/04_classes_objects/01_enums.md
@@ -17,7 +17,7 @@ toc:
- Precautions {precautions}
- Conclusion {conclusion}
description: "Working with enums."
-last_update: 2023-09-29
+last_update: 2023-10-02
author: ["DanielSchmid"]
---
@@ -71,11 +71,11 @@ switch (someDay) {
}
```
-With [Switch Expressions](id:lang.classes-objects.switch-expression),
+With [Switch Expressions](id:lang.basics.switch_expressions),
the compiler can check whether all values of the enum are handled.
If any possible value is missing in a switch expression, there will be a compiler error.
This is referred to as Exhaustiveness and can also be achieved with regular classes
-through [Sealed Classes](https://openjdk.org/jeps/409).
+through [Sealed Classes](jep:409).
```java
DayOfWeek someDay = DayOfWeek.FRIDAY;
@@ -210,6 +210,6 @@ and reading these configuration files in the program in cases like this.
## Conclusion
-Enums provide a simple and safe way of representing a fixed set of constants while keeping most of the flexibilities of classes. They are a special type of class that can be used to write code that is elegant, readable, and maintainable, and work well with other newer modern features like [Switch Expressions](id:lang.classes-objects.switch-expression). Another special class is the Record class introduced in Java 19. Visit our [Records tutorial](id:lang.records) to learn more.
+Enums provide a simple and safe way of representing a fixed set of constants while keeping most of the flexibilities of classes. They are a special type of class that can be used to write code that is elegant, readable, and maintainable, and work well with other newer modern features like [Switch Expressions](id:lang.basics.switch_expressions). Another special class is the Record class introduced in Java 19. Visit our [Records tutorial](id:lang.records) to learn more.
To learn more about enums, visit the [`java.lang.Enum`](javadoc:Enum) javadoc.
\ No newline at end of file
diff --git a/app/pages/learn/01_tutorial/04_mastering-the-api/02_modern_io/01_modern_io.md b/app/pages/learn/01_tutorial/04_mastering-the-api/02_modern_io/01_modern_io.md
index 54e86ee..5bd0496 100644
--- a/app/pages/learn/01_tutorial/04_mastering-the-api/02_modern_io/01_modern_io.md
+++ b/app/pages/learn/01_tutorial/04_mastering-the-api/02_modern_io/01_modern_io.md
@@ -7,13 +7,19 @@ category_order: 2
layout: learn/tutorial.html
subheader_select: tutorials
main_css_id: learn
+toc:
+ - Introduction {introduction}
+ - Reading Text Files {reading-text-files}
+ - Writing Text Files {writing-text-files}
+ - The Files API {the-files-api}
+ - Conclusion {conclusion}
last_update: 2024-04-24
description: "This article focuses on tasks that application programmers are likely to encounter, particularly in web applications, such as reading and writing text files, reading text, images, JSON from the web, and more."
author: ["CayHorstmann"]
---
-
+
## Introduction
This article focuses on tasks that application programmers are likely to encounter, particularly in web applications, such as:
@@ -24,15 +30,16 @@ This article focuses on tasks that application programmers are likely to encount
* Reading a ZIP file
* Creating a temporary file or directory
-The Java API supports many other tasks, which are explained in detail in the [Java I/O API tutorial](https://dev.java/learn/java-io/).
+The Java API supports many other tasks, which are explained in detail in the [Java I/O API tutorial](id:api.javaio.overview).
This article focuses on API improvements since Java 8. In particular:
-* UTF-8 is the default for I/O since Java 18 ([JEP 400](https://openjdk.org/jeps/400))
-* The `java.nio.file.Files` class, which first appeared in Java 7, added useful methods in Java 8, 11, and 12
-* `java.io.InputStream` gained useful methods in Java 9, 11, and 12
-* The `java.io.File` and `java.io.BufferedReader` classes are now thoroughly obsolete, even though they appear frequently in web searches and AI chats.
+* UTF-8 is the default for I/O since Java 18 (since [UTF-8 by Default](jep:400))
+* The [`java.nio.file.Files`](javadoc:Files) class, which first appeared in Java 7, added useful methods in Java 8, 11, and 12
+* [`java.io.InputStream`](javadoc:InputStream) gained useful methods in Java 9, 11, and 12
+* The [`java.io.File`](javadoc:File) and [`java.io.BufferedReader`](javadoc:BufferedReader) classes are now thoroughly obsolete, even though they appear frequently in web searches and AI chats.
+
## Reading Text Files
You can read a text file into a string like this:
@@ -41,13 +48,13 @@ You can read a text file into a string like this:
String content = Files.readString(path);
```
-Here, `path` is an instance of `java.nio.Path`, obtained like this:
+Here, `path` is an instance of [`java.nio.Path`](javadoc:Path), obtained like this:
```java
var path = Path.of("/usr/share/dict/words");
```
-Before Java 18, you were strongly encouraged to specify the character encoding with any file operations that read or write strings. Nowadays, by far the most common character encoding is UTF-8, but for backwards compatibility, Java used the "platform encoding", which can be a legacy encoding on Windows. To ensure portability, text I/O operations needed parameters `StandardCharsets.UTF_8`. This is no longer necessary.
+Before Java 18, you were strongly encouraged to specify the character encoding with any file operations that read or write strings. Nowadays, by far the most common character encoding is UTF-8, but for backwards compatibility, Java used the "platform encoding", which can be a legacy encoding on Windows. To ensure portability, text I/O operations needed parameters [`StandardCharsets.UTF_8`](javadoc:StandardCharsets.UTF_8). This is no longer necessary.
If you want the file as a sequence of lines, call
@@ -55,7 +62,7 @@ If you want the file as a sequence of lines, call
List lines = Files.readAllLines(path);
```
-If the file is large, process the lines lazily as a `Stream`:
+If the file is large, process the lines lazily as a [`Stream`](javadoc:Stream):
```java
try (Stream lines = Files.lines(path)) {
@@ -63,20 +70,21 @@ try (Stream lines = Files.lines(path)) {
}
```
-Also use `Files.lines` if you can naturally process lines with stream operations (such as `map`, `filter`). Note that the stream returned by `Files.lines` needs to be closed. To ensure that this happens, use a `try`-with-resources statement, as in the preceding code snippet.
+Also use [`Files.lines`](javadoc:Files.lines(Path)) if you can naturally process lines with stream operations (such as [`map`](javadoc:Stream.map(Function)), [`filter`](javadoc:Stream.filter(Predicate))). Note that the stream returned by [`Files.lines`](javadoc:Files.lines(Path)) needs to be closed. To ensure that this happens, use a _try-with-resources_ statement, as in the preceding code snippet.
-There is no longer a good reason to use the `readLine` method of `java.io.BufferedReader`.
+There is no longer a good reason to use the [`readLine`](javadoc:BufferedReader.readLine()) method of [`java.io.BufferedReader`](javadoc:BufferedReader).
-To split your input into something else than lines, use a `java.util.Scanner`. For example, here is how you can read words, separated by non-letters:
+To split your input into something else than lines, use a [`java.util.Scanner`](javadoc:Scanner). For example, here is how you can read words, separated by non-letters:
```java
Stream tokens = new Scanner(path).useDelimiter("\\PL+").tokens();
```
-The `Scanner` class also has methods for reading numbers, but it is generally simpler to read the input as one string per line, or a single string, and then parse it.
+The [`Scanner`](javadoc:Scanner) class also has methods for reading numbers, but it is generally simpler to read the input as one string per line, or a single string, and then parse it.
-Be careful when parsing numbers from text files, since their format may be locale-dependent. For example, the input `100.000` is 100.0 in the US locale but 100000.0 in the German locale. Use `java.text.NumberFormat` for locale-specific parsing. Alternatively, you may be able to use `Integer.parseInt`/`Double.parseDouble`.
+Be careful when parsing numbers from text files, since their format may be locale-dependent. For example, the input `100.000` is 100.0 in the US locale but 100000.0 in the German locale. Use [`java.text.NumberFormat`](javadoc:NumberFormat) for locale-specific parsing. Alternatively, you may be able to use [`Integer.parseInt`](javadoc:Integer.parseInt(String))/[`Double.parseDouble`](javadoc:Double.parseDouble(String)).
+
## Writing Text Files
You can write a string to a text file with a single call:
@@ -93,18 +101,18 @@ List lines = . . .;
Files.write(path, lines);
```
-For more general output, use a `PrintWriter` if you want to use the `printf` method:
+For more general output, use a [`PrintWriter`](javadoc:PrintWriter) if you want to use the [`printf`](javadoc:PrintWriter.printf()) method:
```java
var writer = new PrintWriter(path.toFile());
writer.printf(locale, "Hello, %s, next year you'll be %d years old!%n", name, age + 1);
```
-Note that `printf` is locale-specific. When writing numbers, be sure to write them in the appropriate format. Instead of using `printf`, consider `java.text.NumberFormat` or `Integer.toString`/`Double.toString`.
+Note that [`printf`](javadoc:PrintWriter.printf()) is locale-specific. When writing numbers, be sure to write them in the appropriate format. Instead of using [`printf`](javadoc:PrintWriter.printf()), consider [`java.text.NumberFormat`](javadoc:NumberFormat) or [`Integer.toString`](javadoc:Integer.toString())/[`Double.toString`](javadoc:Double.toString(double)).
-Weirdly enough, as of Java 21, there is no `PrintWriter` constructor with a `Path` parameter.
+Weirdly enough, as of Java 21, there is no [`PrintWriter`](javadoc:PrintWriter) constructor with a [`Path`](javadoc:Path) parameter.
-If you don't use `printf`, you can use the `BufferedWriter` class and write strings with the `write` method.
+If you don't use [`printf`](javadoc:PrintWriter.printf()), you can use the [`BufferedWriter`](javadoc:BufferedWriter) class and write strings with the [`write`](javadoc:BufferedWriter.write(int)) method.
```java
var writer = Files.newBufferedWriter(path);
@@ -114,11 +122,12 @@ writer.newLine();
Remember to close the `writer` when you are done.
+
## Reading From an Input Stream
Perhaps the most common reason to use a stream is to read something from a web site.
-If you need to set request headers or read response headers, use the `HttpClient`:
+If you need to set request headers or read response headers, use the [`HttpClient`](javadoc:HttpClient):
```java
HttpClient client = HttpClient.newBuilder().build();
@@ -164,19 +173,20 @@ Map result = JSON.std.mapFrom(url);
Here is how to read the dog image from the preceding call:
```java
-url = new URI(result.get("message").toString()).toURL();
-BufferedImage img = javax.imageio.ImageIO.read(url)
+URL url = new URI(result.get("message").toString()).toURL();
+BufferedImage img = javax.imageio.ImageIO.read(url);
```
-This is better than passing an input stream to the `read` method, because the library can use additional information from the URL to determine the image type.
+This is better than passing an input stream to the [`read`](javadoc:ImageIO.read(URL)) method, because the library can use additional information from the URL to determine the image type.
+
## The Files API
-The `java.nio.file.Files` class provides a comprehensive set of file operations, such as creating, copying, moving, and deleting files and directories. The [File System Basics](https://dev.java/learn/java-io/file-system/) tutorial provides a thorough description. In this section, I highlight a few common tasks.
+The [`java.nio.file.Files`](javadoc:Files) class provides a comprehensive set of file operations, such as creating, copying, moving, and deleting files and directories. The [File System Basics](id:api.javaio.file_sytem.intro) tutorial provides a thorough description. In this section, I highlight a few common tasks.
### Traversing Entries in Directories and Subdirectories
-For most situations you can use one of two methods. The `Files.list` method visits all entries (files, subdirectories, symbolic links) of a directory.
+For most situations you can use one of two methods. The [`Files.list`](javadoc:Files.list(Path)) method visits all entries (files, subdirectories, symbolic links) of a directory.
```java
try (Stream entries = Files.list(pathToDirectory)) {
@@ -184,9 +194,9 @@ try (Stream entries = Files.list(pathToDirectory)) {
}
```
-Use a `try`-with-resources statement to ensure that the stream object, which keeps track of the iteration, will be closed.
+Use a _try-with-resources_ statement to ensure that the stream object, which keeps track of the iteration, will be closed.
-If you also want to visit the entries of descendant directories, instead use the method
+If you also want to visit the entries of descendant directories, instead use the method [`Files.walk`](javadoc:Files.walk(Path))
```java
Stream entries = Files.walk(pathToDirectory);
@@ -203,15 +213,15 @@ try (Stream entries = Files.walk(pathToDirectory)) {
Here are the other methods for traversing directory entries:
-* An overloaded version of `Files.walk` lets you limit the depth of the traversed tree.
-* Two `Files.walkFileTree` methods provide more control over the iteration process, by notifying a `FileVisitor` when a directory is visited for the first and last time. This can be occasionally useful, in particularly for emptying and deleting a tree of directories. See the tutorial [Walking the File Tree](https://dev.java/learn/java-io/file-system/walking-tree) for details. Unless you need this control, use the simpler `Files.walk` method.
-* The `Files.find` method is just like `Files.walk`, but you provide a filter that inspects each path and its `BasicFileAttributes`. This is slightly more efficient than reading the attributes separately for each file.
-* Two `Files.newDirectoryStream` methods yields `DirectoryStream` instances, which can be used in enhanced `for` loops. There is no advantage over using `Files.list`.
-* The legacy `File.list` or `File.listFiles` methods return file names or `File` objects. These are now obsolete.
+* An overloaded version of [`Files.walk`](javadoc:Files.walk(Path,depth)) lets you limit the depth of the traversed tree.
+* Two [`Files.walkFileTree`](javadoc:Files.walkFileTree(Path)) methods provide more control over the iteration process, by notifying a [`FileVisitor`](javadoc:FileVisitor) when a directory is visited for the first and last time. This can be occasionally useful, in particularly for emptying and deleting a tree of directories. See the tutorial [Walking the File Tree](id:api.javaio.file_sytem.walking_tree) for details. Unless you need this control, use the simpler [`Files.walk`](javadoc:Files.walk(Path)) method.
+* The [`Files.find`](javadoc:Files.find(Path)) method is just like [`Files.walk`](javadoc:Files.walk(Path)), but you provide a filter that inspects each path and its [`BasicFileAttributes`](javadoc:BasicFileAttributes). This is slightly more efficient than reading the attributes separately for each file.
+* Two [`Files.newDirectoryStream(Path)`](javadoc:Files.newDirectoryStream(Path)) methods yields [`DirectoryStream`](javadoc:DirectoryStream) instances, which can be used in enhanced `for` loops. There is no advantage over using [`Files.list`](javadoc:Files.list(Path)).
+* The legacy [`File.list`](javadoc:File.list()) or [`File.listFiles`](javadoc:File.listFiles()) methods return file names or [`File`](javadoc:File) objects. These are now obsolete.
### Working with ZIP Files
-Ever since Java 1.1, the `ZipInputStream` and `ZipOutputStream` classes provide an API for processing ZIP files. But the API is a bit clunky. Java 8 introduced a much nicer *ZIP file system*:
+Ever since Java 1.1, the [`ZipInputStream`](javadoc:ZipInputStream) and [`ZipOutputStream`](javadoc:ZipOutputStream) classes provide an API for processing ZIP files. But the API is a bit clunky. Java 8 introduced a much nicer *ZIP file system*:
```java
try (FileSystem fs = FileSystems.newFileSystem(pathToZipFile)) {
@@ -219,9 +229,9 @@ try (FileSystem fs = FileSystems.newFileSystem(pathToZipFile)) {
}
```
-The `try`-with-resources statement ensures that the `close` method is called after the ZIP file operations. That method updates the ZIP file to reflect any changes in the file system.
+The _try-with-resources_ statement ensures that the [`close`](javadoc:AutoCloseable.close()) method is called after the ZIP file operations. That method updates the ZIP file to reflect any changes in the file system.
-You can then use the methods of the `Files` class. Here we get a list of all files in the ZIP file:
+You can then use the methods of the [`Files`](javadoc:Files) class. Here we get a list of all files in the ZIP file:
```java
try (Stream entries = Files.walk(fs.getPath("/"))) {
@@ -229,35 +239,36 @@ try (Stream entries = Files.walk(fs.getPath("/"))) {
}
```
-To read the file contents, just use `Files.readString` or `Files.readAllBytes`:
+To read the file contents, just use [`Files.readString`](javadoc:Files.readString(Path)) or [`Files.readAllBytes`](javadoc:Files.readAllBytes(Path)):
```java
String contents = Files.readString(fs.getPath("/LICENSE"));
```
-You can remove files with `Files.delete`. To add or replace files, simply use `Files.writeString` or `Files.write`.
+You can remove files with [`Files.delete`](javadoc:Files.delete()). To add or replace files, simply use [`Files.writeString`](javadoc:Files.writeString()) or [`Files.write`](javadoc:Files.write()).
### Creating Temporary Files and Directories
Fairly often, I need to collect user input, produce files, and run an external process. Then I use temporary files, which are gone after the next reboot, or a temporary directory that I erase after the process has completed.
-The calls
+I use the two methods [`Files.createTempFile`](javadoc:Files.createTempFile(String,String,FileAttribute)) and [`Files.createTempDirectory`](javadoc:Files.createTempDirectory(Path,String,FileAttribute...)) for that.
```java
Path filePath = Files.createTempFile("myapp", ".txt");
Path dirPath = Files.createTempDirectory("myapp");
```
-create a temporary file or directory in a suitable location (`/tmp` in Linux) with the given prefix and, for a file, suffix.
+This creates a temporary file or directory in a suitable location (`/tmp` in Linux) with the given prefix and, for a file, suffix.
+
## Conclusion
Web searches and AI chats can suggest needlessly complex code for common I/O operations. There are often better alternatives:
1. You don't need a loop to read or write strings or byte arrays.
2. You may not even need a stream, reader or writer.
-3. Become familiar with the `Files` methods for creating, copying, moving, and deleting files and directories.
-4. Use `Files.list` or `Files.walk` to traverse directory entries.
+3. Become familiar with the [`Files`](javadoc:Files) methods for creating, copying, moving, and deleting files and directories.
+4. Use [`Files.list`](javadoc:Files.list(Path)) or [`Files.walk`](javadoc:Files.walk(Path)) to traverse directory entries.
5. Use a ZIP file system for processing ZIP files.
-6. Stay away from the legacy `File` class.
+6. Stay away from the legacy [`File`](javadoc:File) class.
diff --git a/gulpfile.js b/gulpfile.js
index 1287329..81d9800 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -27,6 +27,7 @@ for (const author of authorsArray) {
var javadoc = require('./app/data/javadoc.json')
var javafxdoc = require('./app/data/javafxdoc.json')
+var jep = require('./app/data/jep.json')
function getAuthorID(name) {
@@ -226,9 +227,9 @@ function pages() {
if (href.includes("javafxdoc:")) {
let javafxdoc_id = href.match(/javafxdoc:([\w\.\-(),]+)/)
if (javafxdoc_id != null) {
- processedHref = processDocLink(javafxdoc["javafxdoc_root"] + javafxdoc[javafxdoc_id[1]]);
+ processedHref = processJavaFxDocLink(javafxdoc["javafxdoc_root"] + javafxdoc[javafxdoc_id[1]]);
if (processedHref.includes("undefined")) {
- console.log("Javadoc " + javafxdoc_id[1] + " resolved to undefined");
+ console.log("JavaFX Javadoc " + javafxdoc_id[1] + " resolved to undefined");
}
return `${text}`;
}
@@ -251,7 +252,37 @@ function pages() {
}
}
+ if (href.includes("jep:")) {
+ let jep_id = href.match(/jep:([\d]+)/);
+ if (jep_id != null) {
+ if (jep[jep_id[1]] == undefined) {
+ console.log("JEP " + jep_id[1] + " is not defined");
+ } else {
+ processedHref = jep["root"] + jep_id[1];
+ let anchor = href.match(/#[\w|-]+/);
+ if (anchor) {
+ processedHref = processedHref + anchor;
+ }
+ if (jep[jep_id[1]]["status"] == "preview" && jep[jep_id[1]]["version"] != javadoc["current_release"]) {
+ console.log(
+ "Current release is " + javadoc["current_release"] + ", JEP " + jep_id[1] +
+ " is a preview of " + jep[jep_id[1]]["version"] + " and still referenced");
+ }
+ if (jep[jep_id[1]]["status"] == "incubator" && jep[jep_id[1]]["version"] != javadoc["current_release"]) {
+ console.log(
+ "Current release is " + javadoc["current_release"] + ", JEP " + jep_id[1] +
+ " is an incubator of " + jep[jep_id[1]]["version"] + " and still referenced");
+ }
+ if (jep[jep_id[1]]["title"]) {
+ text = "JEP " + jep_id[1] + ": " + jep[jep_id[1]]["title"];
+ } else {
+ text = "JEP " + jep_id[1] + ": " + jep[jep_id[1]];
+ }
+ return `${text}`;
+ }
+ }
+ }
if (title) {
link = `${text}`;
@@ -402,6 +433,10 @@ function processDocLink(link) {
return link.replace("@@CURRENT_RELEASE@@", javadoc[`current_release`]);
}
+function processJavaFxDocLink(link) {
+ return link.replace("@@CURRENT_RELEASE@@", javafxdoc[`current_release`]).replace("@@RELEASE_UUID@@", javafxdoc[`release_uuid`]);
+}
+
function is_tutorial(file) {
return file.fm.type == "tutorial" || file.fm.type == "tutorial-group";