Removed JavaService, and moved Java handling to CmlLib.

This commit is contained in:
2026-04-06 14:50:29 +01:00
parent 7b66d8ceac
commit 0415d6ad80
2 changed files with 0 additions and 332 deletions

View File

@@ -1,15 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
using AlayaCore.Installation;
using AlayaCore.Models.Manifests;
namespace AlayaCore.Abstractions.Interfaces.Services
{
public interface IJavaService
{
Task EnsureValidJavaInstalledAsync(
ManifestModel manifest,
InstallEnvironment environment,
CancellationToken cancellationToken = default);
}
}

View File

@@ -1,317 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using AlayaCore.Abstractions.Interfaces;
using AlayaCore.Abstractions.Interfaces.Services;
using AlayaCore.Installation;
using AlayaCore.Models.Manifests;
using AlayaCore.Utilities.Enums;
namespace AlayaCore.Services
{
public sealed class JavaService : IJavaService
{
private const string JavaArchiveHashPlaceholder = "REPLACE_WITH_MANIFEST_HASH_SUPPORT";
private const string BaseUrl = "https://aka.ms/download-jdk/";
private readonly IDownloadService _downloadService;
private readonly IFileStore _fileStore;
public JavaService(IDownloadService downloadService, IFileStore fileStore)
{
_downloadService = downloadService ?? throw new ArgumentNullException(nameof(downloadService));
_fileStore = fileStore ?? throw new ArgumentNullException(nameof(fileStore));
}
public async Task EnsureValidJavaInstalledAsync(
ManifestModel manifest,
InstallEnvironment environment,
CancellationToken cancellationToken = default)
{
if (manifest == null)
{
throw new ArgumentNullException(nameof(manifest));
}
if (environment == null)
{
throw new ArgumentNullException(nameof(environment));
}
cancellationToken.ThrowIfCancellationRequested();
string installDirectory = GetJavaInstallDirectory();
if (environment.JavaInstalled &&
Directory.Exists(installDirectory) &&
string.Equals(environment.JavaVersion, manifest.RequiredJavaVersion, StringComparison.OrdinalIgnoreCase))
{
return;
}
if (Directory.Exists(installDirectory))
{
await RemoveDirectoryAsync(installDirectory, cancellationToken).ConfigureAwait(false);
}
Uri downloadUri = GetPlatformSpecificJavaUri(manifest.RequiredJavaVersion);
string downloadPath = GetJavaDownloadPath(downloadUri);
Directory.CreateDirectory(Path.GetDirectoryName(downloadPath) ?? AppContext.BaseDirectory);
Directory.CreateDirectory(installDirectory);
await DownloadJavaAsync(
downloadUri,
downloadPath,
cancellationToken).ConfigureAwait(false);
await InstallJavaAsync(
downloadPath,
installDirectory,
cancellationToken).ConfigureAwait(false);
}
public Uri GetPlatformSpecificJavaUri(string javaVersion)
{
if (string.IsNullOrWhiteSpace(javaVersion))
{
throw new ArgumentException("Java version must be provided.", nameof(javaVersion));
}
string os = GetOsSegment();
string arch = GetArchitectureSegment();
string extension = GetFileExtension(os);
string fileName = $"microsoft-jdk-{javaVersion}-{os}-{arch}.{extension}";
return new Uri($"{BaseUrl}{fileName}");
}
private string GetJavaInstallDirectory()
{
return _fileStore.GetOrCreate(FolderLocation.Java);
}
private string GetJavaDownloadPath(Uri downloadUri)
{
if (downloadUri == null)
{
throw new ArgumentNullException(nameof(downloadUri));
}
string fileName = Path.GetFileName(downloadUri.AbsolutePath);
if (string.IsNullOrWhiteSpace(fileName))
{
throw new InvalidOperationException("Could not determine Java archive file name from download URI.");
}
return Path.Combine(_fileStore.GetOrCreate(FolderLocation.Downloads), fileName);
}
private static string GetOsSegment()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return "windows";
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return "linux";
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return "macos";
}
throw new PlatformNotSupportedException("Unsupported operating system.");
}
private static string GetArchitectureSegment()
{
return RuntimeInformation.OSArchitecture switch
{
Architecture.X64 => "x64",
Architecture.Arm64 => "aarch64",
Architecture.X86 => throw new NotSupportedException("X86 is not supported."),
Architecture.Arm => throw new NotSupportedException("Arm32 is not supported."),
_ => throw new PlatformNotSupportedException(
$"Unsupported architecture: {RuntimeInformation.OSArchitecture}")
};
}
private static string GetFileExtension(string os)
{
return os switch
{
"windows" => "zip",
"linux" => "tar.gz",
"macos" => "tar.gz",
_ => throw new PlatformNotSupportedException($"Unsupported OS: {os}")
};
}
private static Task RemoveDirectoryAsync(
string directoryPath,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(directoryPath))
{
throw new ArgumentException("Directory path cannot be null, empty, or whitespace.", nameof(directoryPath));
}
cancellationToken.ThrowIfCancellationRequested();
if (Directory.Exists(directoryPath))
{
Directory.Delete(directoryPath, recursive: true);
}
return Task.CompletedTask;
}
private async Task DownloadJavaAsync(
Uri javaUri,
string destinationPath,
CancellationToken cancellationToken = default)
{
if (javaUri == null)
{
throw new ArgumentNullException(nameof(javaUri));
}
if (!javaUri.IsAbsoluteUri)
{
throw new ArgumentException("Java download URI must be absolute.", nameof(javaUri));
}
if (string.IsNullOrWhiteSpace(destinationPath))
{
throw new ArgumentException("Destination path cannot be null, empty, or whitespace.", nameof(destinationPath));
}
cancellationToken.ThrowIfCancellationRequested();
string directory = Path.GetDirectoryName(destinationPath);
if (!string.IsNullOrWhiteSpace(directory))
{
Directory.CreateDirectory(directory);
}
if (File.Exists(destinationPath))
{
File.Delete(destinationPath);
}
await _downloadService.DownloadFileAsync(
javaUri,
destinationPath,
JavaArchiveHashPlaceholder,
cancellationToken: cancellationToken).ConfigureAwait(false);
}
private static async Task InstallJavaAsync(
string archivePath,
string installDirectory,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(archivePath))
{
throw new ArgumentException("Archive path cannot be null, empty, or whitespace.", nameof(archivePath));
}
if (string.IsNullOrWhiteSpace(installDirectory))
{
throw new ArgumentException("Install directory cannot be null, empty, or whitespace.", nameof(installDirectory));
}
cancellationToken.ThrowIfCancellationRequested();
if (!File.Exists(archivePath))
{
throw new FileNotFoundException("Java archive was not found.", archivePath);
}
Directory.CreateDirectory(installDirectory);
if (archivePath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
{
ZipFile.ExtractToDirectory(archivePath, installDirectory);
return;
}
if (archivePath.EndsWith(".tar.gz", StringComparison.OrdinalIgnoreCase))
{
await ExtractTarGzAsync(archivePath, installDirectory, cancellationToken).ConfigureAwait(false);
return;
}
throw new NotSupportedException(
$"Unsupported Java archive format: {Path.GetFileName(archivePath)}");
}
private static async Task ExtractTarGzAsync(
string archivePath,
string destinationDirectory,
CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(archivePath))
{
throw new ArgumentException("Archive path cannot be null, empty, or whitespace.", nameof(archivePath));
}
if (string.IsNullOrWhiteSpace(destinationDirectory))
{
throw new ArgumentException("Destination directory cannot be null, empty, or whitespace.", nameof(destinationDirectory));
}
Directory.CreateDirectory(destinationDirectory);
var startInfo = new ProcessStartInfo
{
FileName = "tar",
Arguments = $"-xzf \"{archivePath}\" -C \"{destinationDirectory}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using var process = new Process { StartInfo = startInfo };
await using (cancellationToken.Register(() =>
{
try
{
if (!process.HasExited)
{
process.Kill();
}
}
catch
{
// Ignore race conditions if the process exits while cancellation is being handled.
}
}))
{
process.Start();
string standardOutput = await process.StandardOutput.ReadToEndAsync().ConfigureAwait(false);
string standardError = await process.StandardError.ReadToEndAsync().ConfigureAwait(false);
await Task.Run(() => process.WaitForExit(), cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
if (process.ExitCode != 0)
{
throw new InvalidOperationException(
$"tar extraction failed with exit code {process.ExitCode}. Error: {standardError}. Output: {standardOutput}");
}
}
}
}
}