All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fathzer.jdbbackup.cron.PluginsManager Maven / Gradle / Ivy

package com.fathzer.jdbbackup.cron;

import static com.fathzer.jdbbackup.DestinationManager.URI_PATH_SEPARATOR;

import java.io.IOException;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.fathzer.jdbbackup.SourceManager;
import com.fathzer.jdbbackup.DestinationManager;
import com.fathzer.jdbbackup.JDbBackup;
import com.fathzer.jdbbackup.cron.plugindownloader.SharedRepositoryDownloader;
import com.fathzer.jdbbackup.cron.parameters.Task;
import com.fathzer.jdbbackup.cron.plugindownloader.RepositoryRecord.Repository;
import com.fathzer.jdbbackup.utils.AbstractManagersDownloader;
import com.fathzer.jdbbackup.utils.Cache;
import com.fathzer.plugin.loader.jar.JarPluginLoader;
import com.fathzer.plugin.loader.utils.FileUtils;
import com.fathzer.plugin.loader.utils.ProxySettings;

import lombok.extern.slf4j.Slf4j;

@Slf4j
class PluginsManager {
	/** The root URI of remote plugin repository. */
	private static final URI REPOSITORY_ROOT_URI = URI.create(System.getProperty("pluginRepository", "https://jdbbackup.github.io/web/repository/"));
	/** The directory where downloaded plugins are stored. */
	public static final Path DOWNLOAD_DIR = Paths.get(System.getProperty("downloadedPlugins", System.getProperty("user.home", "")),".jdbbackup");
	private static final boolean CLEAR_DOWNLOAD_DIR = Boolean.getBoolean("clearDownloadedPlugins");

	private SharedRepositoryDownloader destManagerDownloader;
	private SharedRepositoryDownloader srcManagerDownloader;

	/** Constructor.
	 * @param version The version of plugins client.
	 */
	PluginsManager(String version) {
		super();
		final URI uri = REPOSITORY_ROOT_URI.resolve(version+".json");
		final Cache cache = new Cache<>(); 
		this.destManagerDownloader = new SharedRepositoryDownloader(uri, DOWNLOAD_DIR.resolve("destinations"), cache, Repository::getDestinationManagers);
		this.destManagerDownloader.setPluginTypeWording("destination manager");
		this.srcManagerDownloader = new SharedRepositoryDownloader(uri, DOWNLOAD_DIR.resolve("sources"), cache, Repository::getSourceManagers);
		this.srcManagerDownloader.setPluginTypeWording("source manager");
	}

	private void load(JDbBackup backup) throws IOException {
		final String dir = System.getenv("pluginsDirectory");
		if (dir != null) {
			final Path file = Paths.get(dir);
			final List files = FileUtils.getJarFiles(file, 1);
			if (!files.isEmpty()) {
				log.info("Loading plugins in {}", files);
				load(backup, files);
			} else {
				log.info("Found no plugin in {}", file);
			}
		}
	}
	
	private void load(JDbBackup backup, List files) {
		final JarPluginLoader loader = new JarPluginLoader();
		for (Path file:files) {
			try {
				loader.getPlugins(file, SourceManager.class).forEach(s -> backup.getSourceManagers().put(s.getScheme(), s));
				loader.getPlugins(file, DestinationManager.class).forEach(d -> backup.getDestinationManagers().put(d.getScheme(), d));
			} catch (IOException e) {
				log.error("Error while loading plugins in "+file,e);
			}
		}
	}
	
	void load(JDbBackup backup, Configuration conf) throws IOException {
		load(backup);
		load(backup.getSourceManagers(), SourceManager::getScheme, SourceManager.class, conf.getTasks().stream().map(Task::getSource).map(this::getScheme),
				"source managers", this.srcManagerDownloader, conf.getProxy());
		load(backup.getDestinationManagers(), DestinationManager::getScheme, DestinationManager.class, conf.getTasks().stream().flatMap(task -> task.getDestinations().stream()).map(this::getScheme),
				"destination managers", this.destManagerDownloader, conf.getProxy());
	}
	
	private  void load(Map registry, Function keyFunction, Class pluginClass, Stream requiredKeys, String wording, AbstractManagersDownloader downloader, ProxySettings proxy) throws IOException {
		if (CLEAR_DOWNLOAD_DIR) {
			downloader.clean();
		}
		final Set missing = getMissing(registry, requiredKeys, wording);
		downloader.setProxy(proxy);
		final Collection files = downloader.download(missing.toArray(String[]::new));
		for (Path file: files) {
			final JarPluginLoader loader = new JarPluginLoader();
			final List plugins = loader.getPlugins(file, pluginClass);
			if (plugins.isEmpty()) {
				log.warn("Found no {} in file {}",wording, file);
			} else {
				register(registry, keyFunction, plugins, file, wording);
			}
		}
	}

	private  void register(Map registry, Function keyFunction, final List plugins, Path file, String wording) {
		final List added = plugins.stream().filter(p -> !registry.containsKey(keyFunction.apply(p))).collect(Collectors.toList());
		added.forEach(p -> registry.put(keyFunction.apply(p), p));
		if (!added.isEmpty()) {
			log.info("{} loaded from file {}",capitalize(wording), file);
			added.forEach(dd -> log.info("  . {} -> {}", keyFunction.apply(dd), dd.getClass().getName()));
		}
	}
	
	 Set getMissing(Map managers, Stream requiredKeys, String wording) {
		log.info(managers.isEmpty()?"No {} installed":"Installed {}:", wording);
		managers.entrySet().forEach(e -> log.info("  . {} -> {}", e.getKey(), e.getValue().getClass().getName()));
		final Set missing = requiredKeys.filter(s -> !managers.containsKey(s)).collect(Collectors.toSet());
		if (!missing.isEmpty()) {
			log.info("{} to search in repository: {}", capitalize(wording), missing);
		}
		return missing;
	}
	
	static String capitalize(String str) {
	    if (str == null || str.length()<=1) {
	    	return str;
	    }
	    return str.substring(0, 1).toUpperCase() + str.substring(1);
	}

	private String getScheme(String address) {
		if (address==null) {
			throw new IllegalArgumentException();
		}
		int index = address.indexOf(':');
		if (index<=0) {
			throw new IllegalArgumentException ("Destination scheme is missing in "+address);
		}
		final String result = address.substring(0, index);
		for (int i=1;i<=2;i++) {
			if (index+i>=address.length() || address.charAt(index+i)!=URI_PATH_SEPARATOR) {
				throw new IllegalArgumentException("Address has not the right format: "+address+" does not not match scheme://path");
			}
		}
		return result;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy