init
This commit is contained in:
commit
e124a47765
19374 changed files with 9806149 additions and 0 deletions
356
Framework/Util/Configuration.cs
Normal file
356
Framework/Util/Configuration.cs
Normal file
|
@ -0,0 +1,356 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Kreta.Framework.Logging;
|
||||
using Kreta.Resources;
|
||||
|
||||
namespace Kreta.Framework
|
||||
{
|
||||
public enum SystemType
|
||||
{
|
||||
[Display(Name = nameof(EnumsResource.Ismeretlen), ResourceType = typeof(EnumsResource))]
|
||||
Ismeretlen = -1,
|
||||
|
||||
[Display(Name = nameof(EnumsResource.Teszt), ResourceType = typeof(EnumsResource))]
|
||||
Teszt = 0,
|
||||
|
||||
[Display(Name = nameof(EnumsResource.KlebelsbergKozpont), ResourceType = typeof(EnumsResource))]
|
||||
KK = 1,
|
||||
|
||||
[Display(Name = nameof(EnumsResource.NemzetiSzakkepzesiEsFelnottkepzesiHivatal), ResourceType = typeof(EnumsResource))]
|
||||
NSZFH = 2,
|
||||
|
||||
[Display(Name = nameof(EnumsResource.HermanOttoIntezet), ResourceType = typeof(EnumsResource))]
|
||||
HOI = 3,
|
||||
|
||||
[Display(Name = nameof(EnumsResource.Azure), ResourceType = typeof(EnumsResource))]
|
||||
AZURE = 4,
|
||||
|
||||
[Display(Name = nameof(EnumsResource.Azure), ResourceType = typeof(EnumsResource))]
|
||||
NSZFH_EMA = 5
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Néhány alaptulajdonság van felvéve, aztan majd lehet bővíteni.
|
||||
/// </summary>
|
||||
public class Configuration : ILogConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration constuctor
|
||||
/// </summary>
|
||||
/// <param name="configurationNode">the main "config" node</param>
|
||||
public Configuration(XmlNode configurationNode)
|
||||
{
|
||||
var cfg = configurationNode;
|
||||
try
|
||||
{
|
||||
ConfigDocument = cfg;
|
||||
// ReSharper disable once DoNotCallOverridableMethodsInConstructor
|
||||
ReadConfig(cfg);
|
||||
}
|
||||
catch (InvalidConfigurationException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new InvalidConfigurationException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
#region Beolvasás
|
||||
|
||||
/// <summary>
|
||||
/// Reads configuration string.
|
||||
/// </summary>
|
||||
/// <param name="confignode">Server config</param>
|
||||
/// <param name="xpath">XPath location of node</param>
|
||||
/// <returns>Configuration value</returns>
|
||||
/// <exception cref="InvalidConfigurationException">Invalid configuration</exception>
|
||||
protected static string ReadString(XmlNode confignode, string xpath)
|
||||
{
|
||||
XmlNode current;
|
||||
if ((current = confignode.SelectSingleNode(xpath)) != null)
|
||||
{
|
||||
return current.InnerText;
|
||||
}
|
||||
throw new InvalidConfigurationException(string.Format("Missing configuration entry: {0}.", xpath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads configuration string.
|
||||
/// </summary>
|
||||
/// <param name="confignode">Server config</param>
|
||||
/// <param name="xpath">XPath location of node</param>
|
||||
/// <param name="defaultValue">The default value if missing from configuration</param>
|
||||
/// <returns>Configuration value</returns>
|
||||
/// <exception cref="InvalidConfigurationException">Invalid configuration</exception>
|
||||
protected static string ReadString(XmlNode confignode, string xpath, string defaultValue)
|
||||
{
|
||||
XmlNode current;
|
||||
return (current = confignode.SelectSingleNode(xpath)) != null ? current.InnerText : defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads configuration list.
|
||||
/// </summary>
|
||||
/// <param name="confignode">Server config</param>
|
||||
/// <param name="xpath">XPath location of node</param>
|
||||
/// <param name="listElementNode">Name of list element node</param>
|
||||
/// <returns>Configuration list</returns>
|
||||
protected static string[] ReadStrings(XmlNode confignode, string xpath, string listElementNode)
|
||||
{
|
||||
XmlNode current;
|
||||
if ((current = confignode.SelectSingleNode(xpath)) != null)
|
||||
{
|
||||
return (
|
||||
from XmlNode node in current.ChildNodes
|
||||
where node.Name.Equals(listElementNode, StringComparison.OrdinalIgnoreCase)
|
||||
select node.InnerText)
|
||||
.ToArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads configuration number.
|
||||
/// </summary>
|
||||
/// <param name="confignode">Server config</param>
|
||||
/// <param name="xpath">XPath location of node</param>
|
||||
/// <param name="defaultValue">The default value if missing from configuration, <c>null</c> value implies required node</param>
|
||||
/// <returns>Configuration value</returns>
|
||||
/// <exception cref="InvalidConfigurationException">
|
||||
/// Invalid configuration or <paramref name="defaultValue"/> is <c>null</c> and node is missing.
|
||||
/// </exception>
|
||||
protected static int ReadNumber(XmlNode confignode, string xpath, int? defaultValue = null)
|
||||
{
|
||||
XmlNode current;
|
||||
if ((current = confignode.SelectSingleNode(xpath)) != null)
|
||||
{
|
||||
if (int.TryParse(current.InnerText, out int innerNumber))
|
||||
{
|
||||
return innerNumber;
|
||||
}
|
||||
throw new InvalidConfigurationException(string.Format("Invalid configuration entry: {0}.", xpath));
|
||||
}
|
||||
if (defaultValue != null)
|
||||
{
|
||||
return (int)defaultValue;
|
||||
}
|
||||
throw new InvalidConfigurationException(string.Format("Missing configuration entry: {0}.", xpath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads configuration switch.
|
||||
/// </summary>
|
||||
/// <param name="confignode">Server config</param>
|
||||
/// <param name="xpath">XPath location of node</param>
|
||||
/// <param name="defaultValue">The default value if missing from configuration, <c>null</c> value implies required node</param>
|
||||
/// <returns>Configuration value</returns>
|
||||
/// <exception cref="InvalidConfigurationException">
|
||||
/// Invalid configuration or <paramref name="defaultValue"/> is <c>null</c> and node is missing.
|
||||
/// </exception>
|
||||
protected static bool ReadBool(XmlNode confignode, string xpath, bool? defaultValue = null)
|
||||
{
|
||||
XmlNode current;
|
||||
if ((current = confignode.SelectSingleNode(xpath)) != null)
|
||||
{
|
||||
if (bool.TryParse(current.InnerText, out var innerBool))
|
||||
{
|
||||
return innerBool;
|
||||
}
|
||||
throw new InvalidConfigurationException(string.Format("Invalid configuration entry: {0}.", xpath));
|
||||
}
|
||||
if (defaultValue != null)
|
||||
{
|
||||
return (bool)defaultValue;
|
||||
}
|
||||
throw new InvalidConfigurationException(string.Format("Missing configuration entry: {0}.", xpath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads configuration enumeration.
|
||||
/// </summary>
|
||||
/// <param name="confignode">Server config</param>
|
||||
/// <param name="xpath">XPath location of node</param>
|
||||
/// <param name="defaultValue">The default value if missing from configuration, <c>null</c> value implies required node</param>
|
||||
/// <returns>Configuration value</returns>
|
||||
/// <exception cref="InvalidConfigurationException">
|
||||
/// Invalid configuration or <paramref name="defaultValue"/> is <c>null</c> and node is missing.
|
||||
/// </exception>
|
||||
protected static TEnum ReadEnum<TEnum>(XmlNode confignode, string xpath, TEnum? defaultValue = null) where TEnum : struct
|
||||
{
|
||||
XmlNode current;
|
||||
if ((current = confignode.SelectSingleNode(xpath)) != null)
|
||||
{
|
||||
if (Enum.TryParse(current.InnerText, true, out TEnum innerEnum))
|
||||
{
|
||||
return innerEnum;
|
||||
}
|
||||
throw new InvalidConfigurationException(string.Format("Invalid configuration entry: {0}.", xpath));
|
||||
}
|
||||
if (defaultValue != null)
|
||||
{
|
||||
return (TEnum)defaultValue;
|
||||
}
|
||||
throw new InvalidConfigurationException(string.Format("Missing configuration entry: {0}.", xpath));
|
||||
}
|
||||
|
||||
protected virtual void ReadConfig(XmlNode confignode)
|
||||
{
|
||||
string xpath = "";
|
||||
try
|
||||
{
|
||||
// Kiszolgáló egyedi neve.
|
||||
xpath = @"/config/server/name";
|
||||
ServerName = ReadString(confignode, xpath);
|
||||
|
||||
// Az adatbázis-kapcsolatot leíró karakterlánc.
|
||||
xpath = @"/config/server/dbconnection";
|
||||
DBConnection = ReadString(confignode, xpath);
|
||||
|
||||
xpath = @"/config/server/globalapidbconnection";
|
||||
GlobalDbConnection = ReadString(confignode, xpath);
|
||||
|
||||
// A naplózás szintje.
|
||||
xpath = @"/config/server/loglevel";
|
||||
ServerLogLevel = ReadEnum<LogLevel>(confignode, xpath);
|
||||
#if !DEBUG
|
||||
// Release szerver legfeljebb INFO részletességű lehet.
|
||||
if (ServerLogLevel < LogLevel.INFO)
|
||||
{
|
||||
ServerLogLevel = LogLevel.INFO;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Munkamenet elévülési ideje.
|
||||
xpath = @"/config/server/sessiontimeout";
|
||||
SessionTimeout = ReadNumber(confignode, xpath);
|
||||
|
||||
// Alapértelmezett nyelv.
|
||||
xpath = @"/config/server/lcid";
|
||||
LCID = ReadNumber(confignode, xpath, 1038);
|
||||
|
||||
xpath = @"/config/server/logdbconnection";
|
||||
_logDbConnection = ReadString(confignode, xpath, DBConnection);
|
||||
|
||||
// Konzolra való naplózás engedélyezése.
|
||||
xpath = @"/config/server/logtoconsole";
|
||||
LogToConsole = ReadBool(confignode, xpath, false);
|
||||
|
||||
// A maximálisan lehozható rekordok száma.
|
||||
xpath = @"/config/server/maxrecordsperrequest";
|
||||
MaximalRecordCountPerRequest = ReadNumber(confignode, xpath, 200);
|
||||
|
||||
xpath = @"/config/server/systemtype";
|
||||
SystemType = ReadEnum<SystemType>(confignode, xpath, SystemType.Ismeretlen);
|
||||
}
|
||||
catch (InvalidConfigurationException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new InvalidConfigurationException(string.Format("Invalid configuration entry: {0}.", xpath), exception);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Mezok
|
||||
|
||||
string _logDbConnection;
|
||||
|
||||
volatile int _sessionTimeout = 10;
|
||||
|
||||
SystemType _systemType = SystemType.Ismeretlen;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tulajdonságok
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló neve.
|
||||
/// </summary>
|
||||
public string ServerName { get; private set; }
|
||||
|
||||
string dbconnection = null;
|
||||
/// <summary>
|
||||
/// Adatbáziskapcsolat-leíró karakterlánc.
|
||||
/// </summary>
|
||||
public string DBConnection
|
||||
{
|
||||
get
|
||||
{
|
||||
return dbconnection;
|
||||
}
|
||||
set
|
||||
{
|
||||
dbconnection = value;
|
||||
|
||||
System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder(dbconnection);
|
||||
DatabaseName = builder.InitialCatalog;
|
||||
}
|
||||
}
|
||||
|
||||
public string GlobalDbConnection { get; set; }
|
||||
|
||||
public string DatabaseName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló naplózási szintje.
|
||||
/// </summary>
|
||||
public LogLevel ServerLogLevel { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló alapértelmezett régiókódja.
|
||||
/// </summary>
|
||||
public int LCID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Munkamenet elévülési ideje, percben.
|
||||
/// </summary>
|
||||
public int SessionTimeout
|
||||
{
|
||||
get { return _sessionTimeout; }
|
||||
set { _sessionTimeout = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rendszer típus
|
||||
/// </summary>
|
||||
public SystemType SystemType
|
||||
{
|
||||
get { return _systemType; }
|
||||
set { _systemType = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A konfiguráció, mint XML dokumentum.
|
||||
/// </summary>
|
||||
public XmlNode ConfigDocument { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Az egy kérésben maximálisan megengedett felhozott rekordok száma.
|
||||
/// </summary>
|
||||
public int MaximalRecordCountPerRequest { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Naplózás konzolra.
|
||||
/// </summary>
|
||||
public bool LogToConsole { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ILogConfig
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló naplózási szintje.
|
||||
/// </summary>
|
||||
LogLevel ILogConfig.LogLevel { get { return ServerLogLevel; } }
|
||||
|
||||
string ILogConfig.ConnectionString { get { return _logDbConnection; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
73
Framework/Util/EntityUtils.cs
Normal file
73
Framework/Util/EntityUtils.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Kreta.Framework.Entities;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
public static class EntityUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Visszaadja az entitásokhoz tartozó aktív kapcsolatokat.
|
||||
/// </summary>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <param name="entitasNevek"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<int, List<EntityConnectionModel>> GetEntitiesConnections(List<int> entityIds, List<string> entitasNevek)
|
||||
{
|
||||
|
||||
// entityhistory szures
|
||||
XDocument xmlDoc = new XDocument(new XElement("EntitasNevek"));
|
||||
foreach (var entitasNev in entitasNevek)
|
||||
{
|
||||
xmlDoc.Root.Add(new XElement("Entitas", entitasNev));
|
||||
}
|
||||
|
||||
var EntitasNevek = xmlDoc.ToString();
|
||||
|
||||
xmlDoc = new XDocument(new XElement("Entitasok"));
|
||||
foreach (var entitasId in entityIds)
|
||||
{
|
||||
xmlDoc.Root.Add(new XElement("EntitasId", entitasId));
|
||||
}
|
||||
|
||||
var EntitasIdk = xmlDoc.ToString();
|
||||
|
||||
var result = new Dictionary<int, List<EntityConnectionModel>>();
|
||||
|
||||
using (SDA.DataProvider.SDACommand command = UserContext.Instance.SDAConnection.CreateCommand())
|
||||
{
|
||||
command.Connection = UserContext.Instance.SDAConnection;
|
||||
command.Transaction = UserContext.Instance.SDATransaction;
|
||||
command.CommandText = @"sp_GetEntitasAktivKapcsolatai";
|
||||
command.CommandType = System.Data.CommandType.StoredProcedure;
|
||||
command.Parameters.Add("EntitasIDk", EntitasIdk);
|
||||
command.Parameters.Add("EntitasNevek", EntitasNevek);
|
||||
|
||||
using (SDA.DataProvider.SDADataReader reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var entitasId = reader.GetInt32(0);
|
||||
var targetTableName = reader.GetString(1);
|
||||
var targetColumnName = reader.GetString(2);
|
||||
var sorokSzama = reader.GetInt32(3);
|
||||
|
||||
if (!result.ContainsKey(entitasId))
|
||||
{
|
||||
result.Add(entitasId, new List<EntityConnectionModel>());
|
||||
}
|
||||
|
||||
result[entitasId].Add(new EntityConnectionModel
|
||||
{
|
||||
TargetTableName = targetTableName,
|
||||
TargetColumnName = targetColumnName,
|
||||
RowsCount = sorokSzama
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
227
Framework/Util/FrameworkEnumExtensions.cs
Normal file
227
Framework/Util/FrameworkEnumExtensions.cs
Normal file
|
@ -0,0 +1,227 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Kreta.Framework.Caching;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
public static class FrameworkEnumExtensions
|
||||
{
|
||||
private static readonly ManualEnumCache ManualEnumCache = SDAServer.Instance.CacheManager.AquireCache<ManualEnumCache>();
|
||||
|
||||
private static readonly DictionaryTableCache DictionaryTableCache = SDAServer.Instance.CacheManager.AquireCache<DictionaryTableCache>();
|
||||
|
||||
public static string GetItemNameFromCache(this int value, int tanevId, string intezmenyAzonosito = null)
|
||||
=> DictionaryTableCache.GetItemName(tanevId, value, intezmenyAzonosito);
|
||||
|
||||
public static int GetDictionaryTypeId(this int value, int tanevId, string intezmenyAzonosito = null)
|
||||
=> DictionaryTableCache.GetById(tanevId, value, intezmenyAzonosito).DictionaryTypeId;
|
||||
|
||||
public static void RemoveFromCache(this int tipusId, int tanevId, int? id = null, string intezmenyAzonosito = null)
|
||||
=> DictionaryTableCache.RemoveKey(tanevId, tipusId, id, intezmenyAzonosito);
|
||||
|
||||
public static List<DictionaryItem> GetItemsByType(this int typeId, int tanevId, bool visibleOnly = false, string intezmenyAzonosito = null)
|
||||
=> DictionaryTableCache.GetByType(tanevId, typeId, visibleOnly, intezmenyAzonosito);
|
||||
|
||||
public static int? GetItemIdByTypeAndName(this int typeId, string name, int tanevId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return new int?();
|
||||
}
|
||||
|
||||
name = name.ToUpper();
|
||||
|
||||
var dictionaryItems = GetItemsByType(typeId, tanevId).ToDictionary(k => k.Name.ToUpper(), v => v.Id);
|
||||
|
||||
if (dictionaryItems.TryGetValue(name, out int value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return new int?();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EnumToList
|
||||
/// </summary>
|
||||
/// <param name="tipusId"></param>
|
||||
/// <param name="tanevId"></param>
|
||||
/// <param name="emptyItem">Ha true, hozzáad a listához egy üres elemet </param>
|
||||
/// <param name="topItems">A topItems-ben szereplő ID-val rendelkező enumok kerülnek a lista elejére</param>
|
||||
/// <param name="toLower"></param>
|
||||
/// <param name="visibleOnly">Az Enum list feltöltésekor szabályozható, hogy a C_VISIBLE értéket figyelembe vegye-e</param>
|
||||
/// <returns>IDictionary<string, string></returns>
|
||||
public static IDictionary<string, string> EnumToList(int tipusId, int tanevId, bool emptyItem = false, List<int> topItems = null, bool toLower = false, bool visibleOnly = true)
|
||||
{
|
||||
var enums = tipusId.GetItemsByType(tanevId, visibleOnly).ToDictionary(di => di.Id.ToString(), di => di.Name);
|
||||
|
||||
return enums.SetDictionaryItemsAdditionalSettings(tanevId, emptyItem, topItems, toLower);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EnumItemListToDictionary
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="enumItemList"></param>
|
||||
/// <param name="tanevId"></param>
|
||||
/// <param name="emptyItem">Ha true, hozzáad a listához egy üres elemet </param>
|
||||
/// <param name="topItems">A topItems-ben szereplő ID-val rendelkező enumok kerülnek a lista elejére</param>
|
||||
/// <param name="toLower"></param>
|
||||
/// <param name="intezmenyAzonosito"></param>
|
||||
/// <returns>IDictionary<string, string></returns>
|
||||
public static IDictionary<string, string> EnumItemListToDictionary<T>(this List<T> enumItemList, int tanevId, bool emptyItem = false, List<int> topItems = null, bool toLower = false, string intezmenyAzonosito = null) where T : Enum
|
||||
{
|
||||
var enums = new Dictionary<string, string>();
|
||||
|
||||
foreach (var genericEnumItem in enumItemList)
|
||||
{
|
||||
var enumItem = Enum.Parse(typeof(T), genericEnumItem.ToString()) as Enum;
|
||||
var enumId = Convert.ToInt32(enumItem);
|
||||
var dictionaryItem = DictionaryTableCache.GetById(tanevId, enumId, intezmenyAzonosito);
|
||||
enums.Add(dictionaryItem.Id.ToString(), dictionaryItem.Name);
|
||||
}
|
||||
|
||||
return enums.SetDictionaryItemsAdditionalSettings(tanevId, emptyItem, topItems, toLower);
|
||||
}
|
||||
|
||||
private static IDictionary<string, string> SetDictionaryItemsAdditionalSettings(this Dictionary<string, string> enums, int tanevId, bool emptyItem, List<int> topItems, bool toLower, string intezmenyAzonosito = null)
|
||||
{
|
||||
if (toLower)
|
||||
{
|
||||
enums = enums.ToDictionary(
|
||||
item => item.Key,
|
||||
item => item.Value.ToLower());
|
||||
}
|
||||
|
||||
if (topItems != null)
|
||||
{
|
||||
var topItemEnums = topItems.Where(x => enums.ContainsKey(x.ToString())).Select(id => DictionaryTableCache.GetById(tanevId, id, intezmenyAzonosito)).ToList();
|
||||
var topItemDictionary = topItemEnums.ToDictionary(a => a.Id.ToString(), b => b.Name);
|
||||
|
||||
enums = topItemDictionary.Union(enums).ToDictionary(k => k.Key, v => v.Value);
|
||||
}
|
||||
|
||||
return SetEmptyItem(emptyItem, enums);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Csak manuális enumok esetén használandó.
|
||||
/// NotSupportedException ha nem manual enum.
|
||||
/// ArgumentException ha nem enum.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="emptyItem"></param>
|
||||
/// <returns></returns>
|
||||
public static IDictionary<string, string> EnumToListManual<T>(bool emptyItem = false) where T : Enum
|
||||
{
|
||||
var enumType = typeof(T);
|
||||
if (!enumType.AssemblyQualifiedName.Contains("Kreta.Enums.ManualEnums"))
|
||||
{
|
||||
throw new NotSupportedException("The given enum is not a manual Enum");
|
||||
}
|
||||
|
||||
//// Can't use type constraints on value types, so have to do check like this
|
||||
if (enumType.BaseType != typeof(Enum))
|
||||
{
|
||||
throw new ArgumentException("T must be of type System.Enum");
|
||||
}
|
||||
|
||||
var enums =
|
||||
ManualEnumCache.GetOrAdd(
|
||||
enumType.FullName,
|
||||
_ =>
|
||||
Enum.GetNames(enumType)
|
||||
.ToDictionary(
|
||||
e => Convert.ToInt32(e.EnumParse<T>()).ToString(),
|
||||
e => GetDisplayName(e.EnumParse<T>())
|
||||
)
|
||||
);
|
||||
|
||||
return SetEmptyItem(emptyItem, enums);
|
||||
}
|
||||
|
||||
private static string GetDisplayName<T>(T enumValue)
|
||||
{
|
||||
string result;
|
||||
//NOTE: Ha van Display attribútum, akkor annak a szövegét szedjük elő!
|
||||
var fieldInfo = enumValue.GetType().GetField(enumValue.ToString());
|
||||
var displayAttributeArray = (DisplayAttribute[])fieldInfo.GetCustomAttributes(typeof(DisplayAttribute), false);
|
||||
|
||||
if (displayAttributeArray.Length > 0)
|
||||
{
|
||||
result = displayAttributeArray[0].GetName();
|
||||
return result;
|
||||
}
|
||||
|
||||
//NOTE: Ha nincs Display attribútum, akkor a StringResourcesId attribútum paramétere alapján a StringResources.kres-ben lévő szöveget szedjük elő!
|
||||
var stringResourcesIdAttribute = enumValue
|
||||
.GetType()
|
||||
.GetMember(enumValue.ToString())[0]
|
||||
.GetCustomAttribute<StringResourcesIdAttribute>();
|
||||
|
||||
if (stringResourcesIdAttribute != null)
|
||||
{
|
||||
//NOTE: OBSOLETE!!! Amint kiírtottuk az összes manual enu
|
||||
result = StringResourcesUtil.GetString(stringResourcesIdAttribute.StringResourcesId);
|
||||
return result;
|
||||
}
|
||||
|
||||
//NOTE: Ha egyik attribútum sincs, akkor az enum-nak a ToString-jével térünk vissza!
|
||||
result = enumValue.ToString();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string GetManualEnumNameFromCache<T>(int enumValue) where T : Enum
|
||||
{
|
||||
var names = EnumToListManual<T>();
|
||||
|
||||
foreach (var n in names)
|
||||
{
|
||||
if (n.Key == enumValue.ToString())
|
||||
{
|
||||
return n.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static IDictionary<string, string> SetEmptyItem(bool emptyItem, Dictionary<string, string> enums)
|
||||
{
|
||||
if (emptyItem)
|
||||
{
|
||||
var lista = new Dictionary<string, string>
|
||||
{
|
||||
{"", StringResourcesUtil.GetString(364)}
|
||||
};
|
||||
|
||||
return lista.Union(enums).ToDictionary(k => k.Key, v => v.Value);
|
||||
}
|
||||
|
||||
return enums;
|
||||
}
|
||||
|
||||
public static T EnumParse<T>(this string value) where T : Enum
|
||||
=> EnumParse<T>(value, false);
|
||||
|
||||
public static T EnumParse<T>(this string value, bool ignoreCase) where T : Enum
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
throw new ArgumentException("Must specify valid information for parsing in the string.", nameof(value));
|
||||
}
|
||||
|
||||
var t = typeof(T);
|
||||
|
||||
if (!t.IsEnum)
|
||||
{
|
||||
throw new ArgumentException("Type provided must be an Enum.", "T");
|
||||
}
|
||||
|
||||
return (T)Enum.Parse(t, value, ignoreCase);
|
||||
}
|
||||
}
|
||||
}
|
29
Framework/Util/GridParameters.cs
Normal file
29
Framework/Util/GridParameters.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
public class GridParameters
|
||||
{
|
||||
public GridParameters()
|
||||
{
|
||||
OrderDictionary = new Dictionary<string, ListSortDirection>();
|
||||
FirstRow = 0;
|
||||
LastRow = -1;
|
||||
LoadResultSetInfo = false;
|
||||
OrderBy = string.Empty;
|
||||
}
|
||||
|
||||
public Dictionary<string, ListSortDirection> OrderDictionary { get; set; }
|
||||
|
||||
public int FirstRow { get; set; }
|
||||
|
||||
public int LastRow { get; set; }
|
||||
|
||||
public bool LoadResultSetInfo { get; set; }
|
||||
|
||||
[Obsolete("Az OrderDictionary-t kell használni a jövőben, mivel a Dal-ból a Web-re lett áthozva a SortingAndPaging-je a grid-eknek. Ha ki lett írtva mindenhol a Dal-os SortingAndPaging, akkor törölni kell!")]
|
||||
public string OrderBy { get; set; }
|
||||
}
|
||||
}
|
161
Framework/Util/LanguageContext.cs
Normal file
161
Framework/Util/LanguageContext.cs
Normal file
|
@ -0,0 +1,161 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
namespace Kreta.Framework
|
||||
{
|
||||
[Serializable]
|
||||
public class LanguageContext
|
||||
{
|
||||
const int Hungarian = 1038;
|
||||
const int Zulu = 1077;
|
||||
const int Urdu = 1056;
|
||||
|
||||
[ThreadStatic]
|
||||
static LanguageContext m_Current;
|
||||
|
||||
static LanguageContext m_DefaultLanguageContext;
|
||||
|
||||
static Dictionary<string, int> m_LanguageIndexes;
|
||||
|
||||
readonly int m_LCID;
|
||||
CultureInfo m_RegionSettings;
|
||||
|
||||
public LanguageContext(int lcid)
|
||||
{
|
||||
m_LCID = lcid;
|
||||
SetCulture(CultureInfo.GetCultureInfo(lcid == Zulu || lcid == Urdu ? Hungarian : lcid)); /* A urdu és zulu nyelvet kvázi magyarnak tekintjük. */
|
||||
}
|
||||
|
||||
public LanguageContext() : this(LanguageContext.DefaultLanguageContext.LCID)
|
||||
{
|
||||
}
|
||||
|
||||
void SetCulture(CultureInfo cultureInfo)
|
||||
{
|
||||
if (cultureInfo.IsNeutralCulture)
|
||||
{
|
||||
SetCulture(CultureInfo.CreateSpecificCulture(cultureInfo.Name));
|
||||
}
|
||||
m_RegionSettings = cultureInfo;
|
||||
}
|
||||
|
||||
static int GetLanguageIndex(CultureInfo cultureInfo)
|
||||
{
|
||||
string key = cultureInfo.Name.ToLower();
|
||||
if (m_LanguageIndexes.TryGetValue(key, out int value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!cultureInfo.IsNeutralCulture)
|
||||
{
|
||||
return GetLanguageIndex(cultureInfo.Parent);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void InitializeLanguageIndexes()
|
||||
{
|
||||
Dictionary<string, int> result = new Dictionary<string, int>();
|
||||
// using( SDA.DataProvider.SDAConnection connection = SDAServer.Instance.CreateConnection() )
|
||||
// {
|
||||
// connection.Open();
|
||||
// using( SDA.DataProvider.SDACommand command = connection.CreateCommand() )
|
||||
// {
|
||||
// command.CommandText = @"
|
||||
//if exists (select 1 from sys.tables where name = 'T_SYSTEMPARAMETER')
|
||||
//begin
|
||||
// select C_VALUE from T_SYSTEMPARAMETER where C_NAME = 'LANGUAGES'
|
||||
//end";
|
||||
// string temp = command.ExecuteScalar() as string;
|
||||
// if( temp != null )
|
||||
// {
|
||||
// string[] languages = temp.Split( ',', ';' );
|
||||
// for( int index = 0; index < languages.Length; index++ )
|
||||
// {
|
||||
// result[languages[index].Trim().ToLower()] = index;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
m_LanguageIndexes = result;
|
||||
}
|
||||
|
||||
public static void Initialize(LanguageContext defaultLanguageContext)
|
||||
{
|
||||
DefaultLanguageContext = defaultLanguageContext;
|
||||
InitializeLanguageIndexes();
|
||||
}
|
||||
|
||||
public static LanguageContext DefaultLanguageContext
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_DefaultLanguageContext == null)
|
||||
{
|
||||
m_DefaultLanguageContext = new LanguageContext(Thread.CurrentThread.CurrentCulture.LCID);
|
||||
}
|
||||
return m_DefaultLanguageContext;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_DefaultLanguageContext = value ?? throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
}
|
||||
|
||||
public static LanguageContext Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Current != null)
|
||||
{
|
||||
return m_Current;
|
||||
}
|
||||
|
||||
if (UserContext.Instance != null)
|
||||
{
|
||||
LanguageContext current = UserContext.Instance.LanguageContext;
|
||||
if (current != null)
|
||||
{
|
||||
return current;
|
||||
}
|
||||
}
|
||||
return DefaultLanguageContext;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Current = value;
|
||||
}
|
||||
}
|
||||
|
||||
public CultureInfo RegionSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_RegionSettings;
|
||||
}
|
||||
}
|
||||
|
||||
public int LCID
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_LCID;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A nyelv rendszerparaméterben definiált indexe.
|
||||
/// </summary>
|
||||
public int LanguageIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetLanguageIndex(m_RegionSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
74
Framework/Util/LanguageUtil.cs
Normal file
74
Framework/Util/LanguageUtil.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// LCID alapján megmondja, hogy hanyadik indexű nyelv mezőt kell nézni.
|
||||
/// </summary>
|
||||
public class LanguageUtil
|
||||
{
|
||||
static Dictionary<string, int> m_LanguageIndexes = null;
|
||||
|
||||
private static LanguageUtil _instance;
|
||||
public static LanguageUtil Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new LanguageUtil();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private LanguageUtil()
|
||||
{
|
||||
InitializeLanguageIndexes();
|
||||
}
|
||||
|
||||
static void InitializeLanguageIndexes()
|
||||
{
|
||||
Dictionary<string, int> result = new Dictionary<string, int>();
|
||||
using (SDA.DataProvider.SDAConnection connection = SDAServer.Instance.CreateConnection())
|
||||
{
|
||||
connection.Open();
|
||||
using (SDA.DataProvider.SDACommand command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = @"select C_VALUE from T_SYSTEMPARAMETER where C_NAME = 'LANGUAGES'";
|
||||
string temp = command.ExecuteScalar() as string;
|
||||
if (temp != null)
|
||||
{
|
||||
string[] languages = temp.Split(',', ';');
|
||||
for (int index = 0; index < languages.Length; index++)
|
||||
{
|
||||
result[languages[index].Trim().ToLower()] = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_LanguageIndexes = result;
|
||||
}
|
||||
|
||||
public int GetLanguageIndex(int LCID)
|
||||
{
|
||||
var cultureInfo = new CultureInfo(LCID);
|
||||
|
||||
string key = cultureInfo.Name.ToLower().Substring(0, 2);
|
||||
if (m_LanguageIndexes.TryGetValue(key, out int value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!cultureInfo.IsNeutralCulture)
|
||||
{
|
||||
return GetLanguageIndex(cultureInfo.Parent.LCID);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
9
Framework/Util/ProtectedAttribute.cs
Normal file
9
Framework/Util/ProtectedAttribute.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class ProtectedAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
746
Framework/Util/SDAServer.cs
Normal file
746
Framework/Util/SDAServer.cs
Normal file
|
@ -0,0 +1,746 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Kreta.Framework.Caching;
|
||||
using Kreta.Framework.Exceptions;
|
||||
using Kreta.Framework.Logging;
|
||||
using Kreta.Framework.Session;
|
||||
using SDA.DataProvider;
|
||||
|
||||
namespace Kreta.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// A kiszolgáló.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Az osztály nem engedi meg, hogy egyszerre több példány is létezzen egyidejűleg.
|
||||
/// </remarks>
|
||||
public abstract class SDAServer : IDisposable
|
||||
{
|
||||
#region Mezők
|
||||
|
||||
/// <summary>
|
||||
/// Szálbiztos védelem az egyedüli példány létrehozásához.
|
||||
/// </summary>
|
||||
protected static readonly object SyncClass = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Szálbiztos védelem.
|
||||
/// </summary>
|
||||
protected readonly object Sync = new object();
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló konfigurációs XML címkéje.
|
||||
/// </summary>
|
||||
protected XmlNode ConfigurationNode;
|
||||
|
||||
/// <summary>
|
||||
/// A leállást okozó kivétel.
|
||||
/// </summary>
|
||||
Exception _stopException;
|
||||
|
||||
/// <summary>
|
||||
/// Többszörös felszabadítás elleni védelem.
|
||||
/// </summary>
|
||||
bool _disposed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Konstruktorok
|
||||
|
||||
/// <summary>
|
||||
/// Az osztály konstruktora.
|
||||
/// </summary>
|
||||
protected SDAServer()
|
||||
{
|
||||
const string errorMessage = "There is a running server.";
|
||||
|
||||
if (Instance != null)
|
||||
{
|
||||
throw new InvalidOperationException(errorMessage);
|
||||
}
|
||||
|
||||
lock (SyncClass)
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
throw new InvalidOperationException(errorMessage);
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Az osztály konstruktora.
|
||||
/// </summary>
|
||||
/// <param name="configNode">A konfigurációt tartalmazó XmlNode</param>
|
||||
protected SDAServer(XmlNode configNode)
|
||||
: this()
|
||||
{
|
||||
try
|
||||
{
|
||||
ConfigurationNode = configNode ?? throw new ArgumentNullException(nameof(configNode));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tulajdonságok
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló egyetlen példánya, ha van.
|
||||
/// </summary>
|
||||
public static SDAServer Instance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló futási állapota.
|
||||
/// </summary>
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló utolsó indítási ideje.
|
||||
/// </summary>
|
||||
public DateTime LastStartup { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló konfigurációja.
|
||||
/// </summary>
|
||||
public Configuration Configuration { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló naplózó funkciókat tartalmazó objektuma.
|
||||
/// </summary>
|
||||
public Logger Logger { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló munkamenet-kezelő objektuma.
|
||||
/// </summary>
|
||||
public SessionManager SessionManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló gyorsítótárait kezelő segédobjektuma.
|
||||
/// </summary>
|
||||
public Kreta.Framework.Caching.CacheManager CacheManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Session kapcsolatot kezelő szolgáltatás.
|
||||
/// </summary>
|
||||
public ConnectionManager ConnectionManager { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Absztrakt tulajdonságok
|
||||
|
||||
public abstract bool ConsoleEnabled { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nyilvános felület
|
||||
|
||||
/// <summary>
|
||||
/// Eldönti hogy egy assembly feldolgozása engedélyezett-e a szerver reflexiós metódusainak.
|
||||
/// </summary>
|
||||
/// <param name="assembly">Az adott assembly.</param>
|
||||
/// <returns><see langword="true"/> ha igen, <see langword="false"/> egyébként.</returns>
|
||||
internal protected virtual bool IsAssemblyAllowed(Assembly assembly)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adatbázis kapcsolathoz egy példány létrehozása, zárt állapotban.
|
||||
/// </summary>
|
||||
public SDAConnection CreateConnection()
|
||||
{
|
||||
// <<Factory Method>>
|
||||
return new SDAConnection(Configuration.DBConnection);
|
||||
}
|
||||
|
||||
public SDAConnection CreateConnection(string connectionString)
|
||||
{
|
||||
// <<Factory Method>>
|
||||
return new SDAConnection(connectionString);
|
||||
}
|
||||
|
||||
public virtual string GetOrganizationIdentifier()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public virtual string GetIntezmenyConnectionString(string intezmenyAzonosito)
|
||||
{
|
||||
return Configuration.DBConnection;
|
||||
}
|
||||
|
||||
public virtual string GetSystemConnectionString(string intezmenyAzonosito)
|
||||
{
|
||||
return Configuration.DBConnection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Karakterlánccá alakítja az objektumot.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A karakterlánc tartalmazza a kiszolgáló nevét, hálózati portszámát, állapotát (fut/nem fut).
|
||||
/// </remarks>
|
||||
/// <returns>Az objektumot leíró karakterlánc.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
if (Configuration == null)
|
||||
{
|
||||
return "SDAServer";
|
||||
}
|
||||
return string.Format(
|
||||
IsRunning ? "{0} (running)" : "{0} (stopped)",
|
||||
Configuration.ServerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A konfiguráció adott nevű tulajdonsága.
|
||||
/// </summary>
|
||||
/// <param name="parametername">A tulajdonság neve.</param>
|
||||
/// <returns>A tulajdonság aktuális értéke.</returns>
|
||||
public virtual object GetConfigurationParameter(string parametername)
|
||||
{
|
||||
return Configuration.GetType().InvokeMember(parametername, BindingFlags.GetProperty, null, Configuration, null);
|
||||
}
|
||||
|
||||
#region Indítás, leállítás
|
||||
|
||||
/// <summary>
|
||||
/// Elindítja a kiszolgálót.
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
// <<Template Method>>
|
||||
lock (Sync)
|
||||
{
|
||||
if (IsRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
IsRunning = true;
|
||||
DoStart();
|
||||
Logger.ServerStarted();
|
||||
LastStartup = DateTime.Now;
|
||||
}
|
||||
catch (ServerStartException)
|
||||
{
|
||||
IsRunning = false;
|
||||
throw;
|
||||
}
|
||||
catch (PanicException)
|
||||
{
|
||||
IsRunning = false;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (Logger != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.ExceptionThrown(exception);
|
||||
}
|
||||
catch (Exception logException)
|
||||
{
|
||||
exception = new AggregateException(exception, logException);
|
||||
}
|
||||
}
|
||||
IsRunning = false;
|
||||
throw new ServerStartException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Leállítja a kiszolgálót.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
if (!IsRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
IsRunning = false;
|
||||
DoStop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Újraindítja a kiszolgálót.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A végrehajtás egyenértékű egy leállítással és egy indítással.
|
||||
/// </remarks>
|
||||
public void Restart()
|
||||
{
|
||||
// <<Template Method>>
|
||||
lock (Sync)
|
||||
{
|
||||
if (!IsRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Stop();
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Biztonságosan leállítja a kiszolgálót, és hibaüzenetet hagy maga után, a leállás pontos okáról.
|
||||
/// </summary>
|
||||
public void Panic(Exception panicException)
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
if (_stopException != null)
|
||||
{
|
||||
throw panicException;
|
||||
}
|
||||
_stopException = panicException;
|
||||
try
|
||||
{
|
||||
DoPanic(panicException);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
catch (Exception stopexception)
|
||||
{
|
||||
// még leállítani sem lehet...
|
||||
ConsoleLogWriter.WriteLine("A kiszolgáló leállítása nem sikerült.");
|
||||
ConsoleLogWriter.WriteLine(ExceptionUtil.ExceptionToString(stopexception));
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new PanicException(panicException);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indítás, leállítás
|
||||
|
||||
/// <summary>
|
||||
/// Elvégzi a kiszolgáló indítását.
|
||||
/// </summary>
|
||||
protected virtual void DoStart()
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
_stopException = null;
|
||||
Configuration = DoReadConfiguration(ConfigurationNode);
|
||||
Logger = new Logger(CreatePrimaryLogWriter());
|
||||
Logger.ConfigurationLoaded();
|
||||
DoInitDatabase(Configuration);
|
||||
CacheManager = CreateCacheManager();
|
||||
InitCacheManager();
|
||||
LanguageContext.Initialize(new LanguageContext(Configuration.LCID));
|
||||
SessionManager = CreateSessionManager(Configuration, CacheManager);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elvégzi a kiszolgáló leállítását.
|
||||
/// </summary>
|
||||
protected virtual void DoStop()
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
if (SessionManager != null)
|
||||
{
|
||||
SessionManager.Dispose();
|
||||
SessionManager = null;
|
||||
}
|
||||
if (Logger != null)
|
||||
{
|
||||
Logger.ServerStopped();
|
||||
Logger = null;
|
||||
}
|
||||
CacheManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Konfiguráció felolvasása.
|
||||
/// </summary>
|
||||
/// <param name="configNode">A beállításokat tartalmazó Xml leíró.</param>
|
||||
protected virtual Configuration DoReadConfiguration(XmlNode configNode)
|
||||
{
|
||||
// <<Factory Method>>
|
||||
return new Configuration(configNode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Létrehozza az alapértelmezett naplóvezető szolgáltatást.
|
||||
/// </summary>
|
||||
protected virtual ILogWriter CreatePrimaryLogWriter()
|
||||
{
|
||||
// <<Factory Method>>
|
||||
return LogUtil.ConfigureLogWriters(Configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Létrehozza a kiszolgáló munkamenet-kezelőjét.
|
||||
/// </summary>
|
||||
protected virtual SessionManager CreateSessionManager(Configuration configuration, Caching.CacheManager cacheManager)
|
||||
{
|
||||
// <<Factory Method>>
|
||||
return new SessionManager(configuration, cacheManager);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Létrehozza a kiszolgáló gyorsítótár-kezelőjét.
|
||||
/// </summary>
|
||||
protected virtual Kreta.Framework.Caching.CacheManager CreateCacheManager()
|
||||
{
|
||||
// <<Factory Method>>
|
||||
return new Kreta.Framework.Caching.CacheManager();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inicializálja a kiszolgáló gyorsítótár-kezelőjét, és létrehozza az alap gyorsítótárakat.
|
||||
/// </summary>
|
||||
protected virtual void InitCacheManager()
|
||||
{
|
||||
CacheManager.AquireCache<StringResourcesCache>();
|
||||
CacheManager.AquireCache<ManualEnumCache>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inicializálja az adatbázis-kapcsolatot.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A metódus létrehozza és megnyitja az adatbázis-kapcsolatot és ellenőrzi, hogy
|
||||
/// megfelelő-e az adatbázis verziója.
|
||||
/// </remarks>
|
||||
/// <param name="configuration">Konfigurációs objektum.</param>
|
||||
protected virtual void DoInitDatabase(Configuration configuration)
|
||||
{
|
||||
Initializer.Initialize(DatabaseType.NativeMSSQL);
|
||||
SDA.DataProvider.Configuration.ErrorRecovery = true;
|
||||
SDA.DataProvider.Configuration.MaxTries = 10;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Pánik
|
||||
|
||||
/// <summary>
|
||||
/// Ismeretlen eredetű kivételt kezel le.
|
||||
/// </summary>
|
||||
/// <param name="exception">A kivétel, ami történt.</param>
|
||||
/// <returns><see langword="true"/>, ha a kiszolgáló újraindítható; egyébként <see langword="false"/>.</returns>
|
||||
protected virtual void DoPanic(Exception exception)
|
||||
{
|
||||
string panicmessage = BuildPanicMessage(exception);
|
||||
LogLastWords(panicmessage);
|
||||
WriteLastWords(panicmessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A leállás naplózása a rendszernaplóba.
|
||||
/// </summary>
|
||||
/// <param name="panicmessage">A naplóbejegyzés szövege.</param>
|
||||
[EventLogPermission(SecurityAction.Demand, PermissionAccess = EventLogPermissionAccess.Write)]
|
||||
protected virtual void LogLastWords(string panicmessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!EventLog.SourceExists(Configuration.ServerName))
|
||||
{
|
||||
EventLog.CreateEventSource(Configuration.ServerName, "SDA");
|
||||
}
|
||||
var log = new EventLog
|
||||
{
|
||||
Log = "SDA",
|
||||
Source = Configuration.ServerName
|
||||
};
|
||||
log.WriteEntry(panicmessage, EventLogEntryType.Error, (int)Events.CRITICAL_EXCEPTION);
|
||||
}
|
||||
catch (System.Security.SecurityException) { }
|
||||
catch (InvalidOperationException) { }
|
||||
catch (Win32Exception) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elkészíti a pánik üzenetet.
|
||||
/// </summary>
|
||||
/// <param name="exception">A pánikot okozó kivétel.</param>
|
||||
/// <returns>A szöveges üzenet.</returns>
|
||||
protected virtual string BuildPanicMessage(Exception exception)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine("Server panic:");
|
||||
builder.AppendLine(DateTime.Now.ToString("yyyy.MM.dd. HH:mm:ss"));
|
||||
if (exception != null)
|
||||
{
|
||||
builder.AppendLine("Exception:");
|
||||
builder.Append(exception).AppendLine();
|
||||
}
|
||||
builder.AppendLine("Call stack:");
|
||||
builder.Append(new StackTrace()).AppendLine();
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kiírja a pánik üzenetet konzolra és fájlba.
|
||||
/// </summary>
|
||||
/// <param name="panicMessage">A hátrahagyandó üzenet</param>
|
||||
/// <returns><see langword="true"/>, ha sikerült; egyébként <see langword="false"/></returns>
|
||||
protected virtual void WriteLastWords(string panicMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
ConsoleLogWriter.WriteLine(panicMessage, LogLevel.FATAL);
|
||||
if (!ConsoleLogWriter.ConsoleEnabled)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||
Console.WriteLine(panicMessage);
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||
Console.WriteLine("SDAServer.WriteLastWords():");
|
||||
Console.WriteLine(exception);
|
||||
Console.ResetColor();
|
||||
}
|
||||
try
|
||||
{
|
||||
string directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LastWords");
|
||||
string fileName = string.Format(CultureInfo.InvariantCulture, @"LW{0:yyyyMMddHHmmss}.txt", DateTime.Now);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
using (var writer = new StreamWriter(Path.Combine(directory, fileName), true))
|
||||
{
|
||||
writer.WriteLine(panicMessage);
|
||||
writer.WriteLine();
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||
Console.WriteLine("SDAServer.WriteLastWords():");
|
||||
Console.WriteLine(exception);
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (disposing)
|
||||
{
|
||||
DoStop();
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (SyncClass)
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~SDAServer()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public abstract class SDAApplicationServer : SDAServer
|
||||
{
|
||||
#region Mezők
|
||||
|
||||
/// <summary>
|
||||
/// A kiszolgáló konfigurációs XML fájljának elérési útvonala.
|
||||
/// </summary>
|
||||
readonly string _configurationPath;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tulajdonságok
|
||||
|
||||
public override bool ConsoleEnabled
|
||||
{
|
||||
get { return ConsoleLogWriter.ConsoleEnabled; }
|
||||
set { ConsoleLogWriter.ConsoleEnabled = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Konstruktorok
|
||||
|
||||
/// <summary>
|
||||
/// Az osztály konstruktora.
|
||||
/// </summary>
|
||||
SDAApplicationServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
Entities.EntityHandler.Init();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Az osztály konstruktora.
|
||||
/// </summary>
|
||||
/// <param name="configPath">A konfigurációs XML állomány elérési útvonala</param>
|
||||
protected SDAApplicationServer(string configPath)
|
||||
: this()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(configPath))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configPath));
|
||||
}
|
||||
|
||||
_configurationPath = configPath;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
protected SDAApplicationServer(XmlNode configNode)
|
||||
: this()
|
||||
{
|
||||
try
|
||||
{
|
||||
ConfigurationNode = configNode ?? throw new ArgumentNullException(nameof(configNode));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected virtual XmlNode LoadConfig(string path)
|
||||
{
|
||||
var doc = new XmlDocument();
|
||||
using (var reader = new StreamReader(path))
|
||||
{
|
||||
doc.LoadXml(reader.ReadToEnd());
|
||||
}
|
||||
return doc.SelectSingleNode(".//config");
|
||||
}
|
||||
|
||||
protected override void DoStart()
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
Logger = new Logger(new ConsoleLogWriter());
|
||||
if (_configurationPath != null)
|
||||
{
|
||||
ConfigurationNode = LoadConfig(_configurationPath);
|
||||
}
|
||||
base.DoStart();
|
||||
}
|
||||
}
|
||||
|
||||
void DoStopImpl()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void DoStop()
|
||||
{
|
||||
lock (Sync)
|
||||
{
|
||||
try
|
||||
{
|
||||
DoStopImpl();
|
||||
}
|
||||
finally
|
||||
{
|
||||
base.DoStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal protected override bool IsAssemblyAllowed(Assembly assembly)
|
||||
{
|
||||
return
|
||||
assembly.FullName.IndexOf(@"interop", StringComparison.OrdinalIgnoreCase) == -1
|
||||
&&
|
||||
assembly.FullName.IndexOf(@"fastreport", StringComparison.OrdinalIgnoreCase) == -1
|
||||
&&
|
||||
assembly.FullName.IndexOf(@"barcode", StringComparison.OrdinalIgnoreCase) == -1
|
||||
&&
|
||||
assembly.FullName.IndexOf(@"manageddataaccessdtc", StringComparison.OrdinalIgnoreCase) == -1;
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
bool _disposed;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (disposing)
|
||||
{
|
||||
DoStopImpl();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
28
Framework/Util/SaltGenerator.cs
Normal file
28
Framework/Util/SaltGenerator.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Security.Cryptography;
|
||||
|
||||
namespace Kreta.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// Só generálására használatos segédosztály
|
||||
/// </summary>
|
||||
public static class SaltGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Generál egy véletlen sót.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A só generálása <see cref="System.Security.Cryptography.RandomNumberGenerator"/> segítségével történik.
|
||||
/// </remarks>
|
||||
/// <returns>Véletlen só karakterláncként, ami csak számjegyekből áll</returns>
|
||||
public static string GenerateSalt()
|
||||
{
|
||||
RandomNumberGenerator generator = RNGCryptoServiceProvider.Create();
|
||||
byte[] randombytes = new byte[8];
|
||||
generator.GetNonZeroBytes(randombytes);
|
||||
ulong salt =
|
||||
((ulong)randombytes[7] << 56) + ((ulong)randombytes[6] << 48) + ((ulong)randombytes[5] << 40) + ((ulong)randombytes[4] << 32) +
|
||||
((ulong)randombytes[3] << 24) + ((ulong)randombytes[2] << 16) + ((ulong)randombytes[1] << 8) + (ulong)randombytes[0];
|
||||
return salt.ToString();
|
||||
}
|
||||
}
|
||||
}
|
59
Framework/Util/StreamUtil.cs
Normal file
59
Framework/Util/StreamUtil.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
public class StreamUtil
|
||||
{
|
||||
public static byte[] ConvertStreamToByteArray(System.IO.Stream stream)
|
||||
{
|
||||
long originalPosition = 0;
|
||||
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
originalPosition = stream.Position;
|
||||
stream.Position = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
byte[] readBuffer = new byte[4096];
|
||||
|
||||
int totalBytesRead = 0;
|
||||
int bytesRead;
|
||||
|
||||
while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
|
||||
{
|
||||
totalBytesRead += bytesRead;
|
||||
|
||||
if (totalBytesRead == readBuffer.Length)
|
||||
{
|
||||
int nextByte = stream.ReadByte();
|
||||
if (nextByte != -1)
|
||||
{
|
||||
byte[] temp = new byte[readBuffer.Length * 2];
|
||||
Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
|
||||
Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
|
||||
readBuffer = temp;
|
||||
totalBytesRead++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte[] buffer = readBuffer;
|
||||
if (readBuffer.Length != totalBytesRead)
|
||||
{
|
||||
buffer = new byte[totalBytesRead];
|
||||
Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (stream.CanSeek)
|
||||
{
|
||||
stream.Position = originalPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
Framework/Util/StringResourcesIdAttribute.cs
Normal file
22
Framework/Util/StringResourcesIdAttribute.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)]
|
||||
public sealed class StringResourcesIdAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds the stringvalue for a value in an enum.
|
||||
/// </summary>
|
||||
public int StringResourcesId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to init a StringValue Attribute
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
public StringResourcesIdAttribute(int id)
|
||||
{
|
||||
StringResourcesId = id;
|
||||
}
|
||||
}
|
||||
}
|
48
Framework/Util/StringResourcesUtil.cs
Normal file
48
Framework/Util/StringResourcesUtil.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
namespace Kreta.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class for compatibility with old stringresources cache
|
||||
/// </summary>
|
||||
public static class StringResourcesUtil
|
||||
{
|
||||
private static string Get(int id, int lcid)
|
||||
{
|
||||
return SDAServer.Instance.CacheManager.AquireCache<Caching.StringResourcesCache>().Get(id, lcid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String visszaadasa ID alapjan a magyar szoveget
|
||||
/// Ha van CustomizedText akkor azt adom vissza
|
||||
/// Egyebkent a defaultot
|
||||
/// </summary>
|
||||
public static string GetString(int id)
|
||||
{
|
||||
int lcid = UserContext.Instance == null ? LanguageContext.Current.LCID : UserContext.Instance.LanguageContext.LCID;
|
||||
return GetString(id, lcid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// String visszaadasa LCID es ID alapjan
|
||||
/// Ha van CustomizedText akkor azt adom vissza
|
||||
/// Egyebkent a defaultot
|
||||
/// </summary>
|
||||
/// <returns>a kivant sztring</returns>
|
||||
public static string GetString(int id, int lcid)
|
||||
{
|
||||
if (lcid == 0)
|
||||
{
|
||||
lcid = 1038;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Get(id, lcid);
|
||||
}
|
||||
catch (DataIntegrityException)
|
||||
{
|
||||
// egyébként pedig Nincs ilyen szöveget adunk vissza
|
||||
return $"[{id}_NincsIlyenSzöveg]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
Framework/Util/StringValueAttribute.cs
Normal file
18
Framework/Util/StringValueAttribute.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for StringEnum
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)]
|
||||
public sealed class StringValueAttribute : Attribute
|
||||
{
|
||||
public StringValueAttribute(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Value { get; }
|
||||
}
|
||||
}
|
20
Framework/Util/StringValueUtils.cs
Normal file
20
Framework/Util/StringValueUtils.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Kreta.Framework.Util
|
||||
{
|
||||
public static class StringValueUtils
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Enum, string> values = new ConcurrentDictionary<Enum, string>();
|
||||
|
||||
public static string GetStringValue(this Enum key)
|
||||
{
|
||||
return values.GetOrAdd(key, k =>
|
||||
k.GetType()
|
||||
.GetMember(k.ToString())[0]
|
||||
.GetCustomAttribute<StringValueAttribute>()?
|
||||
.Value);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue