This commit is contained in:
skidoodle 2024-03-13 00:33:46 +01:00
commit e124a47765
19374 changed files with 9806149 additions and 0 deletions

View 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
}
}

View 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;
}
}
}

View 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&lt;string, string&gt;</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&lt;string, string&gt;</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);
}
}
}

View 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; }
}
}

View 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);
}
}
}
}

View 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;
}
}
}

View 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
View 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
}
}

View 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();
}
}
}

View 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;
}
}
}
}
}

View 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;
}
}
}

View 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]";
}
}
}
}

View 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; }
}
}

View 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);
}
}
}