using System;
using System.Collections;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using Kreta.Framework.Localization;
using Kreta.Framework.Logging;
namespace Kreta.Framework
{
///
/// A keretrendszer kivételeinek absztrakt ősosztálya.
///
[FriendlyName(1000003, "Ismeretlen rendszerhiba történt.")]
[LogLevel(LogLevel.ERROR)]
[ErrorCode(Events.FRAMEWORK_EXCEPTION)]
[Serializable]
public abstract class FrameworkException : Exception
{
///
/// Belső osztály a nyelvesítés támogatására.
///
sealed class FrameworkExceptionLocalizer : ExceptionLocalizer
{
public override string Localize(Exception exception, CultureInfo cultureInfo)
{
return ReplaceParameters(exception as FrameworkException, base.Localize(exception, cultureInfo), cultureInfo);
}
static string ReplaceParameters(FrameworkException exception, string template, CultureInfo cultureInfo)
{
if (exception == null)
{
return template;
}
if (string.IsNullOrWhiteSpace(template))
{
return exception.Message;
}
string result = template;
foreach (DictionaryEntry entry in exception.Data)
{
string placeholder = "{" + entry.Key + "}";
object value = entry.Value;
result = result.Replace(placeholder, value != null ? Localizer.Localize(value, cultureInfo) : "N/A");
}
result = result.Replace("{InnerException}", exception.InnerException != null ? Localizer.Localize(exception.InnerException, cultureInfo) : "");
result = result.Replace("{Message}", exception.Message);
result = result.Replace("{Id}", exception.Id);
string formattedClientErrorCode = string.Format(CultureInfo.InvariantCulture, "{0} ({1})", exception.ClientErrorCode, (int)exception.ClientErrorCode);
result = result.Replace("{ClientErrorCode}", formattedClientErrorCode);
return result.Trim();
}
}
const string _errorMessage = "Unknown system error occurred.";
///
/// Az osztály statikus konstruktora.
///
static FrameworkException()
{
Localizer.SetLocalizer(typeof(FrameworkException), new FrameworkExceptionLocalizer());
}
///
/// Az osztály konstruktora.
///
/// A kivétel üzenete
/// A belső kivétel
protected FrameworkException(string message, Exception innerException)
: base(message, innerException)
{
// ReSharper disable DoNotCallOverridableMethodsInConstructor
Data["$Id"] = Guid.NewGuid().ToString();
Data["$IsLogged"] = false;
// ReSharper restore DoNotCallOverridableMethodsInConstructor
}
///
/// Az osztály alapértelmezett konstruktora.
///
protected FrameworkException()
: this(_errorMessage, null) { }
///
/// Az osztály konstruktora.
///
/// A kivétel üzenete
protected FrameworkException(string message)
: this(message, null) { }
///
/// Az osztály konstruktora.
///
/// Sorosítási adatok
/// Sorosítási adatfolyam
protected FrameworkException(SerializationInfo info, StreamingContext context)
: base(info, context) { }
///
/// Beállítja egy paraméter értékét.
///
/// A paraméter neve
/// A paraméter értéke
protected internal void SetValue(string key, object value)
{
if (value != null
&&
key != null
&&
key.Length > 0)
{
Data[key] = value;
}
}
///
/// Naplózási szint.
///
internal LogLevel LogLevel
{
get
{
LogLevelAttribute attribute =
GetType()
.GetCustomAttributes(typeof(LogLevelAttribute), true)
.OfType()
.FirstOrDefault();
return attribute == null ? LogLevel.UNKNOWN : attribute.LogLevel;
}
}
///
/// A kivétel üzenete.
///
public override string Message
{
get
{
var result = base.Message;
foreach (DictionaryEntry entry in Data)
{
string placeholder = "{" + entry.Key + "}";
object value = entry.Value;
result = result.Replace(placeholder, value != null ? value.ToString() : "N/A");
}
return result;
}
}
///
/// A kivétel adattartalma XML-ben.
///
public string DataXml
{
get
{
var result = "";
foreach (DictionaryEntry entry in Data.Cast().Where(entry => entry.Key.ToString() != "RequestXml"))
{
result += "- ";
object value = entry.Value;
string valuestring = value != null ? value.ToString() : "N/A";
result += valuestring;
result += "
";
}
result += "";
return result;
}
}
///
/// A kliensre visszaadott hibakód.
///
internal Events ClientErrorCode
{
get
{
ErrorCodeAttribute attribute =
GetType()
.GetCustomAttributes(typeof(ErrorCodeAttribute), true)
.OfType()
.FirstOrDefault();
return attribute == null ? Events.GENERAL : attribute.ErrorCode;
}
}
///
/// A kivétel azonosítója, naplózáshoz használt.
///
internal string Id
{
get
{
string result = Data["$Id"] as string;
if (result != null)
{
return result;
}
result = Guid.NewGuid().ToString();
Data["$Id"] = result;
return result;
}
}
///
/// A kivétel naplózva lett-e már, vagy sem.
///
internal bool IsLogged
{
get
{
return Equals(Data["$IsLogged"], true);
}
}
///
/// Naplózottá minősíti a kivételt.
///
internal void SetLogged()
{
Data["$IsLogged"] = true;
}
}
}