PageRenderTime 52ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Implementation/trunk/eXpand.ExpressApp.Modules/ModelArtifactState/ArtifactStateRuleManager.cs

#
C# | 223 lines | 208 code | 8 blank | 7 comment | 50 complexity | f508055a9d7ffa2931817302c8efb37d MD5 | raw file
  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using DevExpress.ExpressApp;
  5. using DevExpress.ExpressApp.DC;
  6. using DevExpress.ExpressApp.Localization;
  7. using DevExpress.ExpressApp.Security;
  8. using DevExpress.Persistent.Base;
  9. using System.Collections.Generic;
  10. using DevExpress.ExpressApp.Utils;
  11. using DevExpress.ExpressApp.Filtering;
  12. using DevExpress.Data.Filtering.Helpers;
  13. using DevExpress.Persistent.Base.Security;
  14. using eXpand.ExpressApp.ModelArtifactState.Attributes;
  15. using eXpand.ExpressApp.ModelArtifactState.Exceptions;
  16. using eXpand.ExpressApp.ModelArtifactState.Security.Permissions;
  17. using eXpand.ExpressApp.ModelArtifactState.StateInfos;
  18. using eXpand.ExpressApp.ModelArtifactState.StateRules;
  19. using eXpand.ExpressApp.Security.Permissions;
  20. namespace eXpand.ExpressApp.ModelArtifactState{
  21. /// <summary>
  22. /// A helper class that allows to manage the process of customizing Model Artifacts.
  23. /// </summary>
  24. ///
  25. public sealed class ArtifactStateRuleManager {
  26. public const BindingFlags MethodRuleBindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
  27. public const int MethodRuleOutParametersCount = 1;
  28. public static readonly Type MethodRuleOutParameterType = typeof(Boolean);
  29. public static readonly Type MethodRuleReturnType = typeof(State);
  30. private readonly Dictionary<ITypeInfo, List<ArtifactStateRule>> rules;
  31. private static IValueManager<ArtifactStateRuleManager> instanceManager;
  32. public static ArtifactStateRuleManager Instance {
  33. get {
  34. if (instanceManager == null) {
  35. instanceManager = ValueManager.CreateValueManager<ArtifactStateRuleManager>();
  36. }
  37. if (instanceManager.Value == null) {
  38. instanceManager.Value = new ArtifactStateRuleManager();
  39. }
  40. return instanceManager.Value;
  41. }
  42. }
  43. private ArtifactStateRuleManager() {
  44. rules = new Dictionary<ITypeInfo, List<ArtifactStateRule>>();
  45. }
  46. public List<ArtifactStateRule> this[ITypeInfo typeInfo]
  47. {
  48. get {
  49. lock (rules) {
  50. List<ArtifactStateRule> result = GetEmptyRules();
  51. while (typeInfo != null && typeInfo.Type != typeof(object)) {
  52. result.AddRange(GetTypeRules(typeInfo));
  53. typeInfo = typeInfo.Base;
  54. }
  55. return result;
  56. }
  57. }
  58. set {
  59. lock (rules) {
  60. rules[typeInfo] = value;
  61. }
  62. }
  63. }
  64. private List<ArtifactStateRule> GetTypeRules(ITypeInfo typeInfo)
  65. {
  66. List<ArtifactStateRule> result;
  67. if (!rules.TryGetValue(typeInfo, out result)) {
  68. result = GetEmptyRules();
  69. rules.Add(typeInfo, result);
  70. }
  71. return result ?? GetEmptyRules();
  72. }
  73. private List<ArtifactStateRule> GetEmptyRules()
  74. {
  75. return new List<ArtifactStateRule>();
  76. }
  77. public static bool NeedsCustomization(ITypeInfo typeInfo) {
  78. return Instance[typeInfo].Count > 0;
  79. }
  80. public static bool NeedsCustomization(View view) {
  81. if (view != null && view.ObjectTypeInfo != null) {
  82. return NeedsCustomization(view.ObjectTypeInfo);
  83. }
  84. return false;
  85. }
  86. /// <summary>
  87. /// Determines whether a passed object satisfies to the target criteria and the editor's customization according to a given business criteria should be performed.
  88. /// </summary>
  89. public static bool Fit(object targetObject, ArtifactStateRule artifactStateRule) {
  90. string criteria = artifactStateRule.NormalCriteria;
  91. if (targetObject == null){
  92. if (string.IsNullOrEmpty(artifactStateRule.EmptyCriteria)){
  93. return true;
  94. }
  95. return !fit(new object(), artifactStateRule.EmptyCriteria);
  96. }
  97. return fit(targetObject, criteria);
  98. }
  99. private static bool fit(object targetObject, string criteria){
  100. Type objectType = targetObject.GetType();
  101. var wrapper = new LocalizedCriteriaWrapper(objectType, criteria);
  102. wrapper.UpdateParametersValues();
  103. var descriptor = new EvaluatorContextDescriptorDefault(objectType);
  104. var evaluator = new ExpressionEvaluator(descriptor, wrapper.CriteriaOperator);
  105. return evaluator.Fit(targetObject);
  106. }
  107. public static IEnumerable<ArtifactStateRule> FillRulesFromPermissions(XafApplication application,ITypeInfo info)
  108. {
  109. if (SecuritySystem.Instance is ISecurityComplex)
  110. if (SecuritySystem.CurrentUser != null)
  111. {
  112. var permissions = ((IUser)SecuritySystem.CurrentUser).Permissions;
  113. SecuritySystem.ReloadPermissions();
  114. foreach (ArtifactStateRulePermission permission in permissions.OfType<ArtifactStateRulePermission>().Where(permission => permission.ObjectType==info.Type))
  115. {
  116. var rule = (ArtifactStateRule)permission;
  117. if (permission is ControllerStateRulePermission){
  118. var rulePermission = (ControllerStateRulePermission)permission;
  119. if (!(string.IsNullOrEmpty(rulePermission.ControllerType)))
  120. ((ControllerStateRule)rule).ControllerType =
  121. application.Modules[0].ModuleManager.ControllersManager.CollectControllers(
  122. typeInfo =>
  123. typeInfo.FullName == rulePermission.ControllerType).
  124. Single().GetType();
  125. }
  126. else
  127. {
  128. var rulePermission = (ActionStateRulePermission)permission;
  129. ((ActionStateRule)rule).ActionId = rulePermission.ActionId;
  130. }
  131. yield return rule;
  132. }
  133. }
  134. }
  135. public static ArtifactStateInfo CalculateArtifactStateInfo(object targetObject, ArtifactStateRule rule)
  136. {
  137. Guard.ArgumentNotNull(rule, "rule");
  138. MethodInfo methodInfo = rule.MethodInfo;
  139. State editorState;
  140. bool active;
  141. if (methodInfo != null) {
  142. editorState = GetEditorStateFromMethod(methodInfo, targetObject, out active);
  143. if (!string.IsNullOrEmpty(rule.NormalCriteria)) {
  144. Tracing.Tracer.LogWarning(
  145. ExceptionLocalizerTemplate
  146. <ConditionalArtifactStateExceptionResourceLocalizer, ConditionalArtifactStateExceptionId>.
  147. GetExceptionMessage(
  148. ConditionalArtifactStateExceptionId.BrokenRuleContainsBothCriteriaAndMethodInfoParameters),
  149. typeof (ArtifactStateRuleAttribute).Name, rule.TypeInfo.FullName, rule.NormalCriteria,
  150. rule.MethodInfo.Name);
  151. }
  152. }
  153. else {
  154. editorState = rule.State;
  155. active = Fit(targetObject, rule);
  156. }
  157. return new ArtifactStateInfo(active, targetObject, editorState, rule);
  158. }
  159. private static State GetEditorStateFromMethod(MethodInfo methodInfo, object targetObject, out bool active) {
  160. Guard.ArgumentNotNull(methodInfo, "methodInfo");
  161. State editorState;
  162. if (!methodInfo.IsStatic && targetObject == null) {
  163. editorState = State.Default;
  164. active = false;
  165. }
  166. else {
  167. var parameters = new object[1];
  168. editorState = (State)methodInfo.Invoke(targetObject, parameters);
  169. active = (bool)parameters[0];
  170. }
  171. return editorState;
  172. }
  173. public static bool IsDisplayedMember(IMemberInfo memberInfo) {
  174. if (memberInfo.Owner.KeyMember == memberInfo) {
  175. return true;
  176. }
  177. return memberInfo.IsPublic && memberInfo.IsVisible && !memberInfo.IsStatic &&
  178. (memberInfo.MemberTypeInfo.IsDomainComponent || memberInfo.Owner.IsDomainComponent);
  179. }
  180. public static IEnumerable<ArtifactStateRuleAttribute> FindAttributes(MethodInfo methodInfo)
  181. {
  182. if (methodInfo != null) {
  183. ParameterInfo[] parameters = methodInfo.GetParameters();
  184. if (methodInfo.ReturnType == MethodRuleReturnType
  185. && !methodInfo.ContainsGenericParameters
  186. && parameters.Length == MethodRuleOutParametersCount
  187. ) {
  188. ParameterInfo parameter = parameters[0];
  189. if (parameter.ParameterType == MethodRuleOutParameterType.MakeByRefType() && parameter.IsOut) {
  190. foreach (ArtifactStateRuleAttribute attribute in methodInfo.GetCustomAttributes(typeof(ArtifactStateRuleAttribute), true))
  191. {
  192. yield return attribute;
  193. }
  194. }
  195. }
  196. }
  197. }
  198. public static IEnumerable<ArtifactStateRuleAttribute> FindAttributes(ITypeInfo typeInfo)
  199. {
  200. if (typeInfo != null) {
  201. return typeInfo.FindAttributes<ArtifactStateRuleAttribute>(true);
  202. }
  203. return null;
  204. }
  205. public static MethodInfo FindMethodRule(Type type, string methodName) {
  206. if (type != null && !string.IsNullOrEmpty(methodName)) {
  207. var parameterModifier = new ParameterModifier(MethodRuleOutParametersCount);
  208. parameterModifier[0] = true;
  209. MethodInfo methodInfo = type.GetMethod(methodName, MethodRuleBindingFlags, null, new[] { MethodRuleOutParameterType.MakeByRefType() }, new[] { parameterModifier });
  210. return methodInfo;
  211. }
  212. return null;
  213. }
  214. }
  215. }