DoNotThrowSpecificExceptions.cs :  » Development » devAdvantage » AnticipatingMinds » KnowledgePack » ErrorHandling » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » devAdvantage 
devAdvantage » AnticipatingMinds » KnowledgePack » ErrorHandling » DoNotThrowSpecificExceptions.cs
using System;
using System.Collections;
using AnticipatingMinds.Genesis.KnowledgeManagement;
using AnticipatingMinds.Genesis.CodeDOM;
using AnticipatingMinds.Genesis.CodeDOM.Utilities;
using AnticipatingMinds.CommonUIControls;
using AnticipatingMinds.Genesis.Effectors;
using AnticipatingMinds.Genesis.Effectors.Utilities;
using System.Xml;
using System.Reflection;
using System.Collections.Specialized;
using AnticipatingMinds.PlatformServices.Configuration;


namespace AnticipatingMinds.KnowledgePack.ErrorHandling{
  public class DoNotThrowSpecificExceptionsTemplate : RuleTemplate
    {
    public DoNotThrowSpecificExceptionsTemplate(string templateId, IDictionary templateProperties):base(templateId,templateProperties)
    {
    }

    public override string Name
    {
      get
      {
        return ResourceManager.GetLocalizedString("DoNotThrowSpecificExceptionsTemplate|Name");
      }
    }
    
    public override string Description
    {
      get
      {
        return ResourceManager.GetLocalizedString("DoNotThrowSpecificExceptionsTemplate|Description");
      }
    }

    public override Rule CreateRule(string ruleId, IDictionary ruleProperties)
    {
      return new DoNotThrowSpecificExceptionsRule(ruleId, Id, ruleProperties);
    }  
    public override AnticipatingMinds.CommonUIControls.PropertyPage[] GetRulePropertiesUI(IDictionary ruleProperties)
    {
      AnticipatingMinds.CommonUIControls.PropertyPage[] pages = new AnticipatingMinds.CommonUIControls.PropertyPage[1];
      pages[0] = new InheritancePropertyPage(ruleProperties); 
      return pages;
    }
  }

  public class DoNotThrowSpecificExceptionsRule : Rule
  {
    #region Work with RegistryConfiguration
    const string CONFIG_UI_ROOT = @"SOFTWARE\Anticipating Minds\DevAdvantage\Appearance\Rules\DoNotThrowSpecificExceptionsTemplate";
    private RegistryConfiguration config = new RegistryConfiguration(CONFIG_UI_ROOT, RegistryConfiguration.RegistryTarget.LocalMachine);
    // array with class names which user use by correction
    private string[] LastUsersAppliedClasses
    {
      get{return config.GetMultiString("LastUsersAppliedClasses");}
      set{ 
        if(Array.IndexOf(config.GetMultiString("LastUsersAppliedClasses"), value) == -1)
          config.SetValue("LastUsersAppliedClasses", value); 
      }
    }
    #endregion
    private class RuleData
    {
      public bool Flag = false;
      /* global variable for use in different method 
       * in initialize  
      */ 
      public RuleViolation CurrentViolation = null;
      /* Using for storage current ReferenceExpression
       * */
      public CodeVariableReferenceExpression CurrentVariableReferenceExpression = null;
      public RuleViolationCollection violations = new RuleViolationCollection();
      public CodeExpression ThrowExcpression = null;
      public CodeClassDeclaration ClassDeclaration = null;
    }
    #region Rule Property
    public new class PropertyName : Rule.PropertyName
    {
      public const string InheritRecommendationList = "InheritRecommendationList";        
    }
    #endregion
    #region InheritRecommendation
    
    private ArrayList InheritRecommendationList
    {
      get
      {
        return GetProperty(PropertyName.InheritRecommendationList, ErrorHandling.ErrorHandlingUtils.DefaultInheritRecommendationList("InheritRecommendationList.xml")) as ArrayList;
      }
      set
      {
        SetProperty(PropertyName.InheritRecommendationList, value);
      }
    }
    
    #endregion

    internal DoNotThrowSpecificExceptionsRule(string id, string templateId, IDictionary ruleProperties) : base(id,templateId,ruleProperties)
    {
    }
  
    public override Type[] TargetedCodeElements
    {
      get
      {
        return targetedCodeElements;
      }
    }
    /* 1. find block Throw and analyze it
     * 1.1 if in block create object check it on incorect type and create violation
     * (method AnalyzeThrowStatement)
     *  1.2 Insert in violation current type
     * 2.1 if in block variable reference check it VariableDeclaration on incorect type and create violation
     * (method AnalyzeThrowStatement)
     * 2.2 create violation 
     * find and insert in violation VariableDeclaration
     * find and insert in violation ObjectCreate 
     * Correct : replace VariableDeclaration and ObjectCreate elements 
     * and update LastUsersAppliedClasses
    */
  
    public override RuleViolation[] Analyze(object codeElement, System.Threading.ManualResetEvent cancelAnalysisEvent)
    {

      CodeThrowStatement throwStatement = codeElement as CodeThrowStatement;
      if(!IsCodeElementInRuleApplicabilityScope(CodeTypeMemberUtils.GetContainingTypeMember(throwStatement)))
        return emptyViolationsList;

      RuleData ruleData = new RuleData();

      ruleData.ThrowExcpression = throwStatement.ToThrow;
      
      #region Get ClassDeclaration object
      CodeElementTrace trace = CodeElementTrace.GetCodeElementTrace(throwStatement);
      for(int traceFrameIndex = trace.Trace.Length-1;traceFrameIndex>=0; traceFrameIndex--)
      {
        if(trace.Trace[traceFrameIndex] is CodeClassDeclaration)
        {
          CodeClassDeclaration classDeclaration = trace.Trace[traceFrameIndex] as CodeClassDeclaration;                                  
          ruleData.ClassDeclaration = classDeclaration;
          break;
        }
      }
      #endregion

      CodeDomWalker.WalkCodeElement(throwStatement.ToThrow ,new CodeDomWalker.WalkerCallback(AnalyzeThrowStatement), ruleData);
      
      if(ruleData.violations.Count != 0)
        return ruleData.violations.ToArray();
      else
        return emptyViolationsList;
      
    }  
    private CodeDomWalker.WalkerCallbackReturn AnalyzeThrowStatement(CodeElement codeElement,CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      if(notificationType != CodeDomWalker.CallBackNotificationType.OnElement)
      {
        return CodeDomWalker.WalkerCallbackReturn.Next;
      }
      RuleData ruleData = applicationData as RuleData;
      
      if(codeElement is CodeObjectCreateExpression && IsThrowParent(codeElement))
      {
        // if in throw object create check it on incorect type
        CodeObjectCreateExpression objectCreateExpression = codeElement as CodeObjectCreateExpression;
        #region Block testing simple case : (throw new "IncorectTypeException()")
        if(CheckVoilation(objectCreateExpression.CreateType as CodeTypeReference, ruleData))
        {
          return CodeDomWalker.WalkerCallbackReturn.Cancel;
        }
        #endregion
      }
      // if element is CodeVariableReferenceExpression check it VariableDeclaration
      if(codeElement is CodeVariableReferenceExpression && IsThrowParent(codeElement))
      {
        CodeVariableReferenceExpression variableReferenceExpression = codeElement as CodeVariableReferenceExpression;
        ruleData.CurrentVariableReferenceExpression = variableReferenceExpression;
        #region Block testing declaration block
        if(CheckVoilation(variableReferenceExpression.VariableDeclaration.DeclarationType as CodeTypeReference, ruleData))
        {
          return CodeDomWalker.WalkerCallbackReturn.Cancel;
        }
        
        #endregion
      }
      
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }
    private bool IsThrowParent(CodeElement codeElement)
    {
      CodeElement parent = codeElement.Parent;
      if(parent is CodeParenthesizedExpression)
      {
        parent = parent.Parent;
      }
      if(parent is CodeThrowStatement)
        return true;
      else return false;
    }
    private CodeDomWalker.WalkerCallbackReturn AnalyzeVariableDeclarationStatementBlock(CodeElement codeElement,CodeDomWalker.CallBackNotificationType notificationType, CodeDomWalkerContext walkerContext,object applicationData)
    {
      if(notificationType != CodeDomWalker.CallBackNotificationType.OnElement)
      {
        return CodeDomWalker.WalkerCallbackReturn.Next;
      }
      if(codeElement is CodeBinaryExpression)
      {
        RuleData ruleData = applicationData as RuleData;
        CodeBinaryExpression binary = codeElement as CodeBinaryExpression;
        string variableTypeName = "";
        if(ruleData.CurrentVariableReferenceExpression.VariableDeclaration.DeclarationType.TypeInfo != null)
          variableTypeName = ruleData.CurrentVariableReferenceExpression.VariableDeclaration.DeclarationType.TypeInfo.FullName;

        if(binary.LeftOperand is CodeVariableReferenceExpression 
          && (binary.LeftOperand as CodeVariableReferenceExpression).VariableDeclaration == ruleData.CurrentVariableReferenceExpression.VariableDeclaration
          && binary.RightOperand is CodeObjectCreateExpression 
          && (binary.RightOperand as CodeObjectCreateExpression).CreateType.TypeInfo != null
          && (binary.RightOperand as CodeObjectCreateExpression).CreateType.TypeInfo.FullName == variableTypeName
          )
        {
          ruleData.CurrentViolation.ViolationData["CreateObjectExcpression"] = binary.RightOperand;
          return CodeDomWalker.WalkerCallbackReturn.Cancel;
        }
      }        
      return CodeDomWalker.WalkerCallbackReturn.Next;
    }  
    // check current type  
    private bool CheckVoilation(CodeTypeReference typeReference, RuleData ruleData)
    {
      foreach(InheritRecommendation inheritRecommendation in InheritRecommendationList)
      {
        if(inheritRecommendation.Directly.Equals("Directly"))
        {
          string inheritTypeName = Type.GetType(inheritRecommendation.Class).FullName;

          if(typeReference.TypeInfo != null && inheritTypeName == typeReference.TypeInfo.FullName)
          {
            CreateViolation(typeReference, ruleData, inheritRecommendation);
            return true;
          }
        }
        else if(inheritRecommendation.Directly.Equals("Indirectly"))
        {
          if(typeReference.TypeInfo != null && typeReference.GetAssemblyTypeManager().IsTypeSubclassOf(typeReference.TypeInfo.FullName,inheritRecommendation.Class))
          {
            CreateViolation(typeReference, ruleData, inheritRecommendation);
            return true;
          }
        }
      }
      return false;
    }
    
    private void CreateViolation(CodeTypeReference typeReference, RuleData ruleData, InheritRecommendation inheritRecommendation)
    {
      RuleViolation violation = new RuleViolation(this, (CodeElement)ruleData.ThrowExcpression);
      violation.Description = ResourceManager.GetLocalizedString("DoNotThrowSpecificExceptionsTemplate|Voilation|Description",CodeTypeReferenceUtils.GetShortestTypeNameReference(typeReference, typeReference.TypeName));
      violation.ViolationData["CodeTypeReference"] = typeReference;
      violation.Severity = RuleViolation.ViolationSeverity.Warning;
      violation.ViolationData["DefaultValue"] = "";
      violation.ViolationData["CodeClassDeclaration"] = ruleData.ClassDeclaration;
      violation.ViolationData["InheritRecommendation"] = inheritRecommendation;
      
      if(typeReference.Parent is CodeObjectCreateExpression)
      {
        violation.ViolationData["CreateObjectExcpression"] = typeReference.Parent as CodeObjectCreateExpression;
      }

      if(typeReference.Parent is CodeVariableDeclarationStatement && ruleData.CurrentVariableReferenceExpression != null)
      {
        ruleData.CurrentViolation = violation;
        ruleData.Flag = false;
        CodeVariableDeclarationStatement declarationStatement = typeReference.Parent as CodeVariableDeclarationStatement;
        foreach(CodeVariableDeclarationMember member in declarationStatement.DeclaredVariables)
        {
          if(member.Name == ruleData.CurrentVariableReferenceExpression.VariableName && member.Initializer != null && member.Initializer is CodeObjectCreateExpression)
          {
            CodeObjectCreateExpression objectCreateExpression = member.Initializer as CodeObjectCreateExpression;
            violation.ViolationData["CreateObjectExcpression"] = objectCreateExpression;
            ruleData.Flag = true;          
          }
        }
        if(ruleData.Flag == false)
        {    
          CodeDomWalker.WalkCodeElement( CodeStatementUtils.GetElementStatement(typeReference.Parent.Parent) ,new CodeDomWalker.WalkerCallback(AnalyzeVariableDeclarationStatementBlock), ruleData);
        }
      }
      
      ArrayList recommendations = inheritRecommendation.Recommendations;
      
      
      RuleViolationCorrection violationCorrection;

      ArrayList correctedClassList = new ArrayList();
      if(recommendations != null)
      {
        foreach(CorrectionRecommendation correction in recommendations)
        {
          if(IsEnteredTypeExists(correction.Class, typeReference, false))
          {
            bool isDefault = (correction.Default == "True") ? true : false ;
            string shortName = CodeTypeReferenceUtils.GetShortestTypeNameReference(typeReference, correction.Class);
            violationCorrection = violation.AddCorrection(String.Format(ResourceManager.GetLocalizedString("DoNotDeriveClassesFromSpecificTypesTemplate|Voilation|Correct"), shortName), isDefault, false);
            violationCorrection.CorrectionData["CorrectedClass"] = shortName;
            violationCorrection.CorrectionData["CorrectedClassFullName"] = correction.Class;
            correctedClassList.Add(correction.Class);
            if(isDefault)
            {
              violation.ViolationData["DefaultValue"] = correction.Class;
            }
          }
        }
      }
      if(LastUsersAppliedClasses != null && LastUsersAppliedClasses.Length != 0)
      {
        for(int i =0; i < LastUsersAppliedClasses.Length; i++)
        {
          if(!correctedClassList.Contains(LastUsersAppliedClasses[i]) && IsEnteredTypeExists(LastUsersAppliedClasses[i], typeReference, false))
          {
            string shortNameUsed = CodeTypeReferenceUtils.GetShortestTypeNameReference(typeReference, LastUsersAppliedClasses[i]);
            violationCorrection = violation.AddCorrection(String.Format(ResourceManager.GetLocalizedString("DoNotDeriveClassesFromSpecificTypesTemplate|Voilation|Correct"), shortNameUsed), false, false);
            violationCorrection.CorrectionData["CorrectedClass"] = shortNameUsed;
            violationCorrection.CorrectionData["CorrectedClassFullName"] = LastUsersAppliedClasses[i];
          }
        }
      }
      violationCorrection = violation.AddCorrection(ResourceManager.GetLocalizedString("ErrorHandling|ChangeTo"), false, true);
      ruleData.violations.Add(violation);  

    }

    public override void Correct(RuleViolationCorrection[] requestedCorrections, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector, System.Threading.ManualResetEvent cancelCorrectionEvent)
    {
      try
      {
        codeEffector.BeginCodeChanges("Changed throw type");
        RenamingCorrectionForm renamingCorrectionForm = new RenamingCorrectionForm(requestedCorrections,codeEffector,cancelCorrectionEvent);
        renamingCorrectionForm.Text = "Specify exception type to throw";
        renamingCorrectionForm.Visible = false;
        renamingCorrectionForm.BindViolationCorrectionDataToUI +=new AnticipatingMinds.Genesis.Effectors.Utilities.RenamingCorrectionForm.BindViolationCorrectionDataToUIDelegate(renamingCorrectionForm_PopulateCorrectionData);
        renamingCorrectionForm.CorrectViolation += new AnticipatingMinds.Genesis.Effectors.Utilities.RenamingCorrectionForm.CorrectViolationDelegate(renamingCorrectionForm_CorrectViolation);
        renamingCorrectionForm.IsCorrectionDataValid += new AnticipatingMinds.Genesis.Effectors.Utilities.RenamingCorrectionForm.IsCorrectionDataValidDelegate(renamingForm_ValidateSuggestedName);
        renamingCorrectionForm.ShowCorrectionUI();
        codeEffector.CommitCodeChanges();
      }
      catch(Exception)
      {
        codeEffector.RollbackCodeChanges();
        throw;
      }
    }
    private void renamingCorrectionForm_PopulateCorrectionData(CorrectionForm sender, RuleViolationCorrection violationCorrection,CodeEffector codeEffector)
    {
      CodeTypeReference typeReference = violationCorrection.Violation.ViolationData["CodeTypeReference"] as CodeTypeReference;
      codeEffector.ActivateCodeLocation( typeReference );
    
      InheritRecommendation inheritRecommendation = violationCorrection.Violation.ViolationData["InheritRecommendation"] as InheritRecommendation;
      string typeInfoFullName = typeReference.TypeName as string;

      RenamingCorrectionForm renamingForm = sender as RenamingCorrectionForm;

      renamingForm.violationDescriptionLabel.Text = violationCorrection.Violation.Description;
      renamingForm.currentValueTextBox.Text = typeInfoFullName;
    
      string defaultValue = violationCorrection.Violation.ViolationData["DefaultValue"] as string;
      if(defaultValue != null && defaultValue.Length > 0)
        renamingForm.defaultSuggestionTextBox.Text = defaultValue;
      else if(inheritRecommendation.Recommendations.Count > 0)
      {
        renamingForm.defaultSuggestionTextBox.Text = (inheritRecommendation.Recommendations[0] as CorrectionRecommendation).Class;
      }else renamingForm.defaultSuggestionTextBox.Text = "";

      renamingForm.sugesstionsListBox.Items.Clear();
      ArrayList correctedClassList = new ArrayList();
      foreach(CorrectionRecommendation correction in inheritRecommendation.Recommendations)
      {
        if(IsEnteredTypeExists(correction.Class, typeReference, false))
          correctedClassList.Add(correction.Class);
      }
      if(LastUsersAppliedClasses != null && LastUsersAppliedClasses.Length != 0)
      {
        for(int i =0; i < LastUsersAppliedClasses.Length; i++)
        {
          if(!correctedClassList.Contains(LastUsersAppliedClasses[i]) && IsEnteredTypeExists(LastUsersAppliedClasses[i], typeReference, false))
            correctedClassList.Add(LastUsersAppliedClasses[i]);
        }
      }
      foreach(object item in correctedClassList)
      {
        renamingForm.sugesstionsListBox.Items.Add(item as string);
      }
    }

    private void renamingCorrectionForm_CorrectViolation(CorrectionForm sender, RuleViolationCorrection requestedCorrection, AnticipatingMinds.Genesis.Effectors.CodeEffector codeEffector,object correctionData)
    {
      CodeTypeReference targetTypeReference = requestedCorrection.Violation.ViolationData["CodeTypeReference"] as CodeTypeReference;
      CodeClassDeclaration classDeclaration = requestedCorrection.Violation.ViolationData["CodeClassDeclaration"] as CodeClassDeclaration;
      if(targetTypeReference == null) return;
    
      InheritRecommendation inheritRecommendation = requestedCorrection.Violation.ViolationData["InheritRecommendation"] as InheritRecommendation;
      
      string changeToValue;
      string changeToValueFullName;
      if(correctionData == null)
      {
        changeToValue = requestedCorrection.CorrectionData["CorrectedClass"]  as string;
        changeToValueFullName = requestedCorrection.CorrectionData["CorrectedClassFullName"]  as string;
      }
      else
      {
        changeToValue = correctionData as String;
        changeToValueFullName = changeToValue;
      }
      
      CodeObjectCreateExpression objectCreate = requestedCorrection.Violation.ViolationData["CreateObjectExcpression"] as CodeObjectCreateExpression;   
      
      changeToValue = CodeTypeReferenceUtils.GetShortestTypeNameReference(classDeclaration, changeToValue);
      
      if(targetTypeReference.Parent is CodeVariableDeclarationStatement)
      {
        if(objectCreate != null)
        {
          codeEffector.ChangeCodeElement(objectCreate.CreateType,objectCreate.CreateType.GetType().GetProperty("TypeName"),changeToValue);
        }
      }
      codeEffector.ChangeCodeElement(targetTypeReference,targetTypeReference.GetType().GetProperty("TypeName"),changeToValue);
      this.LastUsersAppliedClasses = ErrorHandlingUtils.InsertToRegistry(this.LastUsersAppliedClasses, changeToValueFullName);
      requestedCorrection.Violation.IsFixed = true;
    }
    private bool renamingForm_ValidateSuggestedName(CorrectionForm sender, RuleViolationCorrection violationCorrection,CodeEffector codeEffector, object correctionData)
    {
      CodeTypeReference typeReference = violationCorrection.Violation.ViolationData["CodeTypeReference"] as CodeTypeReference;
      string correctedString = correctionData as string;
      if(!IsEnteredTypeExists(correctedString, typeReference, true))
      { return false; }
      else{ return true;}
    }
    private bool IsEnteredTypeExists(string typeName, CodeElement codeElement, bool showMessage)
    {
      CodeAssemblyTypeManager manager = codeElement.GetAssemblyTypeManager();
      if(manager != null)
      {
        CodeTypeInfo typeInfo = manager.FindType(typeName);
        if(typeInfo == null)
        {
          if(showMessage) System.Windows.Forms.MessageBox.Show(ResourceManager.GetLocalizedString("ErrorHandling|NotExistsType"));
          return false;
        }
        else
        {
          return true;
        }
      }
      return false;
    }
    private static RuleViolation[] emptyViolationsList = new  RuleViolation[0];
    private Type[] targetedCodeElements = {typeof(CodeThrowStatement)};
    private static Type[] applicableApplicabilityScopeTypes = {typeof(MethodApplicabilityScope),typeof(PropertyApplicabilityScope),typeof(EventApplicabilityScope),typeof(FileApplicabilityScope)};
    public override Type[] ApplicableApplicabilityScopeTypes
    {
      get
      {
        return applicableApplicabilityScopeTypes;
      }
    }
  }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.