2024-03-13 22:16:40 +03:00
|
|
|
|
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
|
|
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
using System;
|
2024-03-13 22:16:40 +03:00
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reflection;
|
2024-05-25 12:26:32 +03:00
|
|
|
|
using Languages.Facade;
|
2024-03-13 22:16:40 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
namespace Languages.Integration
|
2024-03-13 22:16:40 +03:00
|
|
|
|
{
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Модуль с функциями загрузки поддерживаемых языков программирования
|
|
|
|
|
|
/// </summary>
|
2024-03-13 22:16:40 +03:00
|
|
|
|
public static class LanguageIntegrator
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
private static readonly LanguageProvider LanguageProvider = LanguageProvider.Instance;
|
2024-03-13 22:16:40 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Имя директории, содержащей установленные плагины языков программирования
|
|
|
|
|
|
/// </summary>
|
2024-03-13 22:16:40 +03:00
|
|
|
|
private const string languageKitsDirectoryName = "LanguageKits";
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Событие, информирующее об успешной загрузке плагина языка
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static event Action<ILanguage> LanguageLoaded;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Событие, информирующее об ошибке загрузки плагина языка
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static event Action<string> LanguageLoadErrorOccured;
|
|
|
|
|
|
|
2024-03-13 22:16:40 +03:00
|
|
|
|
/// <summary>
|
2024-03-22 23:25:02 +03:00
|
|
|
|
/// Возвращает директорию, содержащую комплекты языков (если ее нет, то вернется null)
|
2024-03-13 22:16:40 +03:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static DirectoryInfo GetLanguageKitsDirectory()
|
|
|
|
|
|
{
|
|
|
|
|
|
string binDirectoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
|
|
|
|
|
string languageKitsDirectoryPath = Path.Combine(binDirectoryPath, languageKitsDirectoryName);
|
|
|
|
|
|
|
2024-03-22 23:25:02 +03:00
|
|
|
|
if (Directory.Exists(languageKitsDirectoryPath))
|
|
|
|
|
|
return new DirectoryInfo(languageKitsDirectoryPath);
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
2024-03-13 22:16:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// Загружает все языковые комплекты для использования (имя "главной" dll должно заканчиваться на Language)
|
2024-03-13 22:16:40 +03:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void LoadAllLanguageKits()
|
|
|
|
|
|
{
|
|
|
|
|
|
DirectoryInfo languageKitsDirectory = GetLanguageKitsDirectory();
|
|
|
|
|
|
|
2024-03-22 23:25:02 +03:00
|
|
|
|
if (languageKitsDirectory == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2024-03-13 22:16:40 +03:00
|
|
|
|
foreach (var languageKit in languageKitsDirectory.GetDirectories())
|
|
|
|
|
|
{
|
|
|
|
|
|
FileInfo[] dllFiles = languageKit.GetFiles();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var dll in dllFiles)
|
|
|
|
|
|
{
|
2024-05-25 12:26:32 +03:00
|
|
|
|
if (dll.Name.EndsWith("Language.dll"))
|
2024-03-13 22:16:40 +03:00
|
|
|
|
{
|
2024-05-25 12:26:32 +03:00
|
|
|
|
IntegrateLanguageFromAssembly(dll);
|
|
|
|
|
|
break;
|
2024-03-13 22:16:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Загружает все языки, доступные в системе
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void LoadAllLanguages()
|
|
|
|
|
|
{
|
2024-05-25 12:26:32 +03:00
|
|
|
|
LoadStandardLanguages();
|
2024-03-22 23:24:19 +03:00
|
|
|
|
LoadAllLanguageKits();
|
2024-03-13 22:16:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// Загружает стандартные языки платформы из папки bin
|
2024-03-13 22:16:40 +03:00
|
|
|
|
/// </summary>
|
2024-05-25 12:26:32 +03:00
|
|
|
|
public static void LoadStandardLanguages()
|
2024-03-13 22:16:40 +03:00
|
|
|
|
{
|
2024-05-25 12:26:32 +03:00
|
|
|
|
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);
|
|
|
|
|
|
|
|
|
|
|
|
DirectoryInfo directory = new DirectoryInfo(directoryName);
|
|
|
|
|
|
|
|
|
|
|
|
FileInfo[] dllFiles = directory.GetFiles("*Language.dll");
|
|
|
|
|
|
|
|
|
|
|
|
foreach (FileInfo languageFile in dllFiles)
|
|
|
|
|
|
{
|
|
|
|
|
|
IntegrateLanguageFromAssembly(languageFile);
|
|
|
|
|
|
}
|
2024-03-13 22:16:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// Загружает плагин языка из dll, содержащей класс, представляющий язык
|
|
|
|
|
|
/// (класс должен реализовывать интерфейс ILanguage и его имя должно заканчиваться на Language)
|
2024-03-13 22:16:40 +03:00
|
|
|
|
/// </summary>
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// <param name="languageFile">dll, содержащая язык</param>
|
|
|
|
|
|
private static void IntegrateLanguageFromAssembly(FileInfo languageFile)
|
2024-03-13 22:16:40 +03:00
|
|
|
|
{
|
2024-05-25 12:26:32 +03:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ILanguage languageFound = InstantiateLanguageAndAddToLanguagesList(languageFile);
|
2024-03-13 22:16:40 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
if (languageFound == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("Language class wasn't found in language assembly. (To be found it should contain 'Language' in it's name)");
|
|
|
|
|
|
}
|
2024-03-22 23:25:02 +03:00
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
LanguageLoaded?.Invoke(languageFound);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (ReflectionTypeLoadException e)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
string errorMessage = e + Environment.NewLine;
|
|
|
|
|
|
errorMessage += "<Loader exceptions>:" + Environment.NewLine;
|
|
|
|
|
|
errorMessage += string.Join(Environment.NewLine, e.LoaderExceptions.Select(error => error.ToString())) + Environment.NewLine;
|
|
|
|
|
|
File.AppendAllText("log.txt", errorMessage);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
LanguageLoadErrorOccured?.Invoke(languageFile.Name);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
2024-03-13 22:16:40 +03:00
|
|
|
|
{
|
2024-05-25 12:26:32 +03:00
|
|
|
|
#if DEBUG
|
|
|
|
|
|
string errorMessage = e + Environment.NewLine;
|
|
|
|
|
|
File.AppendAllText("log.txt", errorMessage);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
LanguageLoadErrorOccured?.Invoke(languageFile.Name);
|
2024-03-13 22:16:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-25 12:26:32 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Конструирует объект языка и добавляет его в список языков в LanguageProvider
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="languageFile"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private static ILanguage InstantiateLanguageAndAddToLanguagesList(FileInfo languageFile)
|
|
|
|
|
|
{
|
|
|
|
|
|
Assembly assembly = Assembly.LoadFile(languageFile.FullName);
|
|
|
|
|
|
|
|
|
|
|
|
Type[] types = assembly.GetTypes();
|
|
|
|
|
|
|
|
|
|
|
|
ILanguage languageFound = null;
|
|
|
|
|
|
foreach (Type type in types)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (type.Name.EndsWith("Language") && type.IsClass)
|
|
|
|
|
|
{
|
|
|
|
|
|
object obj = Activator.CreateInstance(type);
|
|
|
|
|
|
if (obj is ILanguage language)
|
|
|
|
|
|
{
|
|
|
|
|
|
languageFound = language;
|
|
|
|
|
|
LanguageProvider.Languages.Add(language);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return languageFound;
|
|
|
|
|
|
}
|
2024-03-13 22:16:40 +03:00
|
|
|
|
}
|
|
|
|
|
|
}
|