<commit_before>package me.coley.recaf.util.self;

import com.nqzero.permit.Permit;
import me.coley.recaf.Recaf;
import me.coley.recaf.util.ClasspathUtil;
import me.coley.recaf.util.Log;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Deque;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * Utility for patching self when missing dependencies.
 *
 * @author Matt
 */
public class SelfPatcher {
	private static final Path DEPENDENCIES_DIR_PATH = Recaf.getDirectory("dependencies");
	private static final String[] DEPENDENCIES = new String[] {
		"https://repo1.maven.org/maven2/org/openjfx/javafx-media/11.0.2/javafx-media-11.0.2-%s.jar",
		"https://repo1.maven.org/maven2/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-%s.jar",
		"https://repo1.maven.org/maven2/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-%s.jar",
		"https://repo1.maven.org/maven2/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-%s.jar"
	};

	/**
	 * Patch in any missing dependencies, if any.
	 */
	public static void patch() {
		// Do nothing if JavaFX is detected
		if (ClasspathUtil.classExists("javafx.application.Platform"))
			return;

		Log.info("Missing JavaFX dependencies, attempting to patch in missing classes");
		// Check if dependencies need to be downloaded
		if (!hasCachedDependencies())
		{
			Log.info(" - No local cache, downloading dependencies...");
			try {
				fetchDependencies();
			} catch(IOException ex) {
				Log.error(ex, "Failed to download dependencies!");
				System.exit(-1);
			}
		} else {
			Log.info(" - Local cache found!");
		}
		// Add the dependencies
		try {
			loadFromCache();
		} catch(IOException ex) {
			Log.error(ex, ex.getMessage());
			System.exit(-1);
		} catch(ReflectiveOperationException ex) {
			Log.error(ex, "Failed to add dependencies to classpath!");
			System.exit(-1);
		}
		Log.info(" - Done!");
	}


	/**
	 * Inject them into the current classpath.
	 *
	 * @throws IOException
	 * 		When the locally cached dependency urls cannot be resolved.
	 * @throws ReflectiveOperationException
	 * 		When the call to add these urls to the system classpath failed.
	 */
	@SuppressWarnings({"unchecked", "rawtypes"})
	private static void loadFromCache() throws IOException, ReflectiveOperationException {
		Log.info(" - Loading dependencies...");
		Log.info(" - Disabling access system");
		// Bypass the access system
		Permit.godMode();
		// Get Jar URLs
		File[] jars = DEPENDENCIES_DIR_PATH.toFile().listFiles();
		if(jars == null)
			throw new IOException("Failed to iterate over dependencies directory!");
		URL[] jarUrls = new URL[jars.length];
		for(int i = 0; i < jars.length; i++)
			jarUrls[i] = new URL("file:/"  + jars[i].getAbsolutePath());
		if (Float.parseFloat(System.getProperty("java.class.version")) > 52) {
			// Fetch UCP of application's ClassLoader
			// - ((ClassLoaders.AppClassLoader) ClassLoaders.appClassLoader()).ucp
			Class<?> clsClassLoaders = Class.forName("jdk.internal.loader.ClassLoaders");
			Object appClassLoader = clsClassLoaders.getDeclaredMethod("appClassLoader").invoke(null);
			Field fieldUCP = appClassLoader.getClass().getDeclaredField("ucp");
			fieldUCP.setAccessible(true);
			Object ucp = fieldUCP.get(appClassLoader);
			Class<?> clsUCP = ucp.getClass();
			Method m = clsUCP.getDeclaredMethod("addURL", URL.class);
			m.setAccessible(true);
			// Add each jar.
			for(int i = 0; i < jars.length; i++) {
				m.invoke(ucp, jarUrls[i]);
			}<commit_msg>Use getVersion()<commit_after>package me.coley.recaf.util.self;

import com.nqzero.permit.Permit;
import me.coley.recaf.Recaf;
import me.coley.recaf.util.ClasspathUtil;
import me.coley.recaf.util.Log;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Deque;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * Utility for patching self when missing dependencies.
 *
 * @author Matt
 */
public class SelfPatcher {
	private static final Path DEPENDENCIES_DIR_PATH = Recaf.getDirectory("dependencies");
	private static final String[] DEPENDENCIES = new String[] {
		"https://repo1.maven.org/maven2/org/openjfx/javafx-media/11.0.2/javafx-media-11.0.2-%s.jar",
		"https://repo1.maven.org/maven2/org/openjfx/javafx-controls/11.0.2/javafx-controls-11.0.2-%s.jar",
		"https://repo1.maven.org/maven2/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-%s.jar",
		"https://repo1.maven.org/maven2/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2-%s.jar"
	};

	/**
	 * Patch in any missing dependencies, if any.
	 */
	public static void patch() {
		// Do nothing if JavaFX is detected
		if (ClasspathUtil.classExists("javafx.application.Platform"))
			return;

		Log.info("Missing JavaFX dependencies, attempting to patch in missing classes");
		// Check if dependencies need to be downloaded
		if (!hasCachedDependencies())
		{
			Log.info(" - No local cache, downloading dependencies...");
			try {
				fetchDependencies();
			} catch(IOException ex) {
				Log.error(ex, "Failed to download dependencies!");
				System.exit(-1);
			}
		} else {
			Log.info(" - Local cache found!");
		}
		// Add the dependencies
		try {
			loadFromCache();
		} catch(IOException ex) {
			Log.error(ex, ex.getMessage());
			System.exit(-1);
		} catch(ReflectiveOperationException ex) {
			Log.error(ex, "Failed to add dependencies to classpath!");
			System.exit(-1);
		}
		Log.info(" - Done!");
	}


	/**
	 * Inject them into the current classpath.
	 *
	 * @throws IOException
	 * 		When the locally cached dependency urls cannot be resolved.
	 * @throws ReflectiveOperationException
	 * 		When the call to add these urls to the system classpath failed.
	 */
	@SuppressWarnings({"unchecked", "rawtypes"})
	private static void loadFromCache() throws IOException, ReflectiveOperationException {
		Log.info(" - Loading dependencies...");
		Log.info(" - Disabling access system");
		// Bypass the access system
		Permit.godMode();
		// Get Jar URLs
		File[] jars = DEPENDENCIES_DIR_PATH.toFile().listFiles();
		if(jars == null)
			throw new IOException("Failed to iterate over dependencies directory!");
		URL[] jarUrls = new URL[jars.length];
		for(int i = 0; i < jars.length; i++)
			jarUrls[i] = new URL("file:/"  + jars[i].getAbsolutePath());
		if (getVersion() > 8) {
			// Fetch UCP of application's ClassLoader
			// - ((ClassLoaders.AppClassLoader) ClassLoaders.appClassLoader()).ucp
			Class<?> clsClassLoaders = Class.forName("jdk.internal.loader.ClassLoaders");
			Object appClassLoader = clsClassLoaders.getDeclaredMethod("appClassLoader").invoke(null);
			Field fieldUCP = appClassLoader.getClass().getDeclaredField("ucp");
			fieldUCP.setAccessible(true);
			Object ucp = fieldUCP.get(appClassLoader);
			Class<?> clsUCP = ucp.getClass();
			Method m = clsUCP.getDeclaredMethod("addURL", URL.class);
			m.setAccessible(true);
			// Add each jar.
			for(int i = 0; i < jars.length; i++) {
				m.invoke(ucp, jarUrls[i]);
			}
{'fraction_non_alphanumeric': 0.1462225832656377, 'fraction_numerical': 0.012591389114541024, 'mean_word_length': 3.9444444444444446, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6812536', 'n_tokens_mistral': 2725, 'n_tokens_neox': 2461, 'n_words': 543}