Newer
Older
ultramine_bootstrap / src / main / java / org / ultramine / bootstrap / task / DependencyResolver.java
@vlad20012 vlad20012 on 31 Jul 2017 5 KB Initial commit
package org.ultramine.bootstrap.task;

import org.apache.commons.io.FileUtils;
import org.ultramine.bootstrap.Constants;
import org.ultramine.bootstrap.util.I18n;
import org.ultramine.bootstrap.UMCoreVersionsRetriever;
import org.ultramine.bootstrap.util.UmSslUtil;
import org.ultramine.bootstrap.deps.IRepository;
import org.ultramine.bootstrap.maven.MavenDependency;
import org.ultramine.bootstrap.maven.MavenLocalRepository;
import org.ultramine.bootstrap.maven.MavenRemoteRepository;
import org.ultramine.bootstrap.deps.IDownloadable;
import org.ultramine.bootstrap.exceptions.ApplicationErrorException;
import org.ultramine.bootstrap.maven.ProjectObjectModel;
import org.ultramine.bootstrap.versioning.DefaultArtifactVersion;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DependencyResolver
{
	public static Set<MavenDependency> load(File dir, String selVersion, boolean update, boolean beta, List<URL> extraRepos, List<String> extraLibs)
	{
		UmSslUtil.checkOrInstall();
		File libraryDir = new File(dir, "libraries");
		File checkSumsDir = new File(libraryDir, "checksums");

		List<IRepository> repositories = new ArrayList<>();
		addMavenLocalIfExists(repositories, findMavenLocal());
		addMavenLocalIfExists(repositories, findMinecraftLibs());
		repositories.addAll(Arrays.asList(
				new MavenRemoteRepository("https://repo1.maven.org/maven2"),
				new MavenRemoteRepository("https://oss.sonatype.org/content/repositories/snapshots"),
				new MavenRemoteRepository("http://files.minecraftforge.net/maven"),
				new MavenRemoteRepository("https://libraries.minecraft.net"),
				new MavenRemoteRepository("http"+(UmSslUtil.isUseHttps() ? "s" : "")+"://maven.ultramine.ru")
		));

		for(URL url : extraRepos)
			try {
				repositories.add(url.getProtocol().equals("file") ? new MavenLocalRepository(new File(url.toURI())) : new MavenRemoteRepository(url.toString()));
			} catch(URISyntaxException e) {
				throw new ApplicationErrorException(e, "error.addrepo.file", url.toString());
			}

		System.out.println(I18n.tlt("stage.versions"));
		String targetVersion = selVersion;
		if(targetVersion == null)
		{
			List<DefaultArtifactVersion> versions = null;
			if(!update)
				versions = retrieveLocalVersions(dir);
			if(versions == null || versions.size() == 0)
			{
				UMCoreVersionsRetriever retr = new UMCoreVersionsRetriever();
				versions = beta ? retr.getBetaVersions() : retr.getStableVersions();
			}

			targetVersion = versions.get(versions.size()-1).getLabel();
		}

		MavenDependency umCoreDep = new MavenDependency(Constants.UM_CORE_GROUP, Constants.UM_CORE_NAME, targetVersion);
		File umCoreFile = new File(dir, umCoreDep.getArtifactFilename());

		Set<MavenDependency> dependencies = new HashSet<>();
		dependencies.addAll(ProjectObjectModel.loadFromArtifact(Constants.UM_REPO, Constants.UM_CORE_GROUP, Constants.UM_CORE_NAME, targetVersion)
				.getRuntimeDependencies());
		dependencies.addAll(extraLibs.stream().map(MavenDependency::new).collect(Collectors.toList()));


		List<IDownloadable> toDownload = dependencies.stream().map(d -> d.resolve(repositories)).collect(Collectors.toList());
		IDownloadable umCoreDownloadable = umCoreDep.resolve(repositories);
		umCoreDownloadable.setOutputDir(dir);
		toDownload.add(umCoreDownloadable);
		System.out.println(I18n.tlt("stage.downloading"));
		toDownload.parallelStream().forEach(d -> {
			try
			{
				d.setCheckSumsDir(checkSumsDir);
				if(d.getOutputDir() == null)
					d.setOutputDir(libraryDir);
				d.download();
			} catch (IOException e) {
				throw new ApplicationErrorException(e, "error.download.dependency", d.toString(), e.toString());
			}
		});

		try
		{
			File symlink = new File(dir, Constants.UM_CORE_NAME+"-latest.jar");
			if(symlink.exists())
				FileUtils.forceDelete(symlink);
			try {
				Files.createSymbolicLink(new File(dir, Constants.UM_CORE_NAME + "-latest.jar").toPath(), umCoreFile.toPath());
			} catch(IOException e) {
				FileUtils.copyFile(umCoreFile, symlink);
			}
		}
		catch(IOException e)
		{
			throw new ApplicationErrorException(e, "error.write.file", Constants.UM_CORE_NAME+"-latest.jar", e.getMessage());
		}

		return dependencies;
	}

	private static List<DefaultArtifactVersion> retrieveLocalVersions(File dir)
	{
		return Stream.of(dir.list((d, name) -> name.startsWith(Constants.UM_CORE_NAME)))
				.map(s -> s.substring(Constants.UM_CORE_NAME.length()+1, s.length()-4))
				.map(s -> new DefaultArtifactVersion(s, s)).sorted().collect(Collectors.toList());
	}

	private static void addMavenLocalIfExists(List<IRepository> list, File repo)
	{
		if(repo != null && repo.exists())
			list.add(new MavenLocalRepository(repo));
	}

	private static File findMavenLocal()
	{
		String home = System.getProperty("user.home");
		if(home != null)
			return new File(home, ".m2"+File.separator+"repository");
		return null;
	}

	private static File findMinecraftLibs()
	{
		return getFromAppdata(".minecraft"+File.separator+"libraries");
	}

	private static File getFromAppdata(String name)
	{
		String osName = System.getProperty("os.name").toLowerCase();
		String home = System.getProperty("user.home", ".");
		File dir;
		if(osName.contains("linux") || osName.contains("unix"))
			dir = new File(home, name);
		else if(osName.contains("win"))
		{
			String appdata = System.getenv("APPDATA");
			if(appdata != null)
				dir = new File(appdata, name);
			else
				dir = new File(home, name);
		}
		else if(osName.contains("mac"))
			dir = new File(home, "Library/Application Support/" + name);
		else
			dir = new File(home, name);
		return dir;
	}
}