diff --git a/wpiutil/src/main/java/edu/wpi/first/util/ClassPreloader.java b/wpiutil/src/main/java/edu/wpi/first/util/ClassPreloader.java new file mode 100644 index 00000000000..6d8e2a9b652 --- /dev/null +++ b/wpiutil/src/main/java/edu/wpi/first/util/ClassPreloader.java @@ -0,0 +1,119 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Paths; + +/** + * Loads classes by name. Can be used at any time, but is most commonly used to preload classes at + * the start of the program to avoid unpredictable delays due to lazy classloading later in program + * execution. + */ +public final class ClassPreloader { + private ClassPreloader() {} + + /** + * Loads classes from an iterable. + * + * @param classNames iterable of class names + * @return Number of classes loaded. + */ + public static int preload(Iterable classNames) { + int count = 0; + for (String i : classNames) { + try { + Class.forName(i); + count++; + } catch (ClassNotFoundException e) { + System.out.println("Could not preload " + i); + } + } + return count; + } + + /** + * Loads classes. + * + * @param classNames array of class names + * @return Number of classes loaded. + */ + public static int preload(String... classNames) { + int count = 0; + for (String i : classNames) { + try { + Class.forName(i); + count++; + } catch (ClassNotFoundException e) { + System.out.println("Could not preload " + i); + } + } + return count; + } + + /** + * Loads classes from a buffered reader. The input is expected to be one class name per line. + * Blank lines and lines starting with a semicolon are ignored. + * + * @param reader Reader + * @return Number of classes loaded. + */ + public static int preload(BufferedReader reader) { + int count = 0; + try { + String line = reader.readLine(); + while (line != null) { + if (!line.isEmpty() && !line.startsWith(";")) { + try { + Class.forName(line); + count++; + } catch (ClassNotFoundException e) { + System.out.println("Could not preload " + line); + } + } + line = reader.readLine(); + } + } catch (IOException e) { + System.out.println("Error when reading preload file: " + e); + } + return count; + } + + /** + * Loads classes from an input stream. The input is expected to be one class name per line. Blank + * lines and lines starting with a semicolon are ignored. + * + * @param stream input stream + * @return Number of classes loaded. + */ + public static int preload(InputStream stream) { + return preload(new BufferedReader(new InputStreamReader(stream))); + } + + /** + * Loads classes from a file. The input is expected to be one class name per line. Blank lines and + * lines starting with a semicolon are ignored. + * + * @param filename filename + * @return Number of classes loaded. + */ + public static int preloadFile(String filename) { + try (BufferedReader reader = + Files.newBufferedReader(Paths.get(filename), StandardCharsets.UTF_8)) { + return preload(reader); + } catch (NoSuchFileException e) { + System.out.println("Could not open preload file " + filename + ": " + e); + } catch (IOException e) { + System.out.println("Could not close preload file " + filename + ": " + e); + } + return 0; + } +}