ErrorCodeExceptionTranslator.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Data » Support » 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 » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Data » Support » ErrorCodeExceptionTranslator.cs
#region License

/*
 * Copyright  2002-2006 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion

#region Imports

using System;
using Common.Logging;
using Spring.Dao;
using Spring.Data.Common;

#endregion

namespace Spring.Data.Support{
  /// <summary>
  /// Implementation of IAdoExceptionTranslator that analyzes provider specific
  /// error codes and translates into the DAO exception hierarchy.
  /// </summary>
  /// <remarks>This class loads the obtains error codes from
  /// the IDbProvider metadata property ErrorCodes  
  /// which defines error code mappings for various providers.
  /// </remarks>
  /// <author>Mark Pollack (.NET)</author>
  public class ErrorCodeExceptionTranslator : IAdoExceptionTranslator
  {
    #region Fields

      private ErrorCodes errorCodes;

        private IAdoExceptionTranslator fallbackTranslator;
      
      private IDbProvider dbProvider;
      
    #endregion

    #region Constants

    /// <summary>
    /// The shared log instance for this class (and derived classes). 
    /// </summary>
    protected static readonly ILog log =
      LogManager.GetLogger(typeof (ErrorCodeExceptionTranslator));

    #endregion

    #region Constructor (s)

        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorCodeExceptionTranslator"/> class.
        /// </summary>
        /// <param name="provider">The data provider.</param>
      public ErrorCodeExceptionTranslator(IDbProvider provider)
      {
          DbProvider = provider;
      }



        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorCodeExceptionTranslator"/> class.
        /// </summary>
        /// <param name="provider">The data provider.</param>
        /// <param name="ec">The error code collection.</param>
        public ErrorCodeExceptionTranslator(IDbProvider provider, ErrorCodes ec)
        {
            DbProvider = provider;
            errorCodes = ec;
        }
        
    

    #endregion

    #region Properties

        /// <summary>
        /// Sets the db provider.
        /// </summary>
        /// <value>The db provider.</value>
      public IDbProvider DbProvider
      {
          set
          {
              dbProvider = value;
                fallbackTranslator = new FallbackExceptionTranslator();
                errorCodes = dbProvider.DbMetadata.ErrorCodes;
              
          }
      }
      
        /// <summary>
        /// Gets the error codes for the provider
        /// </summary>
        /// <value>The error codes.</value>
      public ErrorCodes ErrorCodes
      {
          get
          {
              return errorCodes;
          }
      }
      
    #endregion

        /// <summary>
        /// Gets or sets the fallback translator to use in case error code based translation
        /// fails.
        /// </summary>
        /// <value>The fallback translator.</value>
      public IAdoExceptionTranslator FallbackTranslator
      {
          get
          {
              return fallbackTranslator;
          }
          set
          {
              fallbackTranslator = value;
          }
      }
      

    #region Methods

    #endregion


        /// <summary>
      /// Translate the given <see cref="System.SystemException"/> into a generic data access exception.
      /// </summary>
      /// <param name="task">A readable string describing the task being attempted.</param>
      /// <param name="sql">The SQL query or update that caused the problem. May be null.</param>
      /// <param name="exception">
      /// The <see cref="System.Exception"/> encountered by the ADO.NET implementation.
      /// </param>
      /// <returns>
      /// A <see cref="Spring.Dao.DataAccessException"/> appropriate for the supplied
      /// <paramref name="exception"/>.
      /// </returns>
        public virtual DataAccessException Translate(string task, string sql, Exception exception)
        {
            if (task == null)
            {
                task = "";
            }
            if (sql == null)
            {
                sql = "";
            }
            string errorCode = ExtractErrorCode(exception);

            // First, try custom translation from overridden method.
            DataAccessException dex = DoTranslate(task, sql, errorCode, exception);
            if (dex != null)
            {
                // Specific exception match found.
                return dex;
            }
            // Looking for a fallback...
            if (log.IsDebugEnabled)
            {
                log.Debug("Unable to translate exception eith errorCode '" + errorCode + "', will use the fallback translator");
            }
            IAdoExceptionTranslator fallback = FallbackTranslator;
            if (fallback != null)
            {
                return FallbackTranslator.Translate(task, sql, exception);
            }
            // We couldn't identify it more precisely.
            return new UncategorizedAdoException(task, sql, errorCode, exception);
            
            
        }

        /// <summary>
        /// Template method for actually translating the given exception.
        /// given <see cref="System.SystemException"/> into a generic data access exception.
        /// </summary>
        /// <param name="task">A readable string describing the task being attempted.</param>
        /// <param name="sql">The SQL query or update that caused the problem. May be null.</param>
        /// <param name="errorCode">The error code.</param>
        /// <param name="exception">The <see cref="System.Exception"/> encountered by the ADO.NET implementation.</param>
        /// <returns>
        /// A <see cref="Spring.Dao.DataAccessException"/> appropriate for the supplied
        /// <paramref name="exception"/>.
        /// </returns>
        /// <remarks>
        /// The passed-in arguments will have been pre-checked.  furthermore, this method is allowed to
        /// return <code>null</code> to indicate that no exception match has been found and that
        /// fallback translation should kick in.
        /// </remarks>
      protected virtual DataAccessException DoTranslate(string task, string sql, string errorCode, Exception exception)
      {
            // First, try custom translation from overridden method.
            DataAccessException dex = TranslateException(task, sql, errorCode, exception);
            if (dex != null)
            {
                return dex;
            }


          if (errorCodes != null)
          {

              if (errorCode != null)
              {
                    if (Array.IndexOf(errorCodes.BadSqlGrammarCodes, errorCode) >= 0)
                  {
                      LogTranslation(task, sql, errorCode, exception, false);
                      return new BadSqlGrammarException(task, sql, exception);
                  }
                    else if (Array.IndexOf(errorCodes.InvalidResultSetAccessCodes, errorCode) >= 0) 
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new InvalidResultSetAccessException(task, sql, exception);
                    }
                    else if (Array.IndexOf(errorCodes.DuplicateKeyCodes, errorCode) >= 0)
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new DuplicateKeyException(task, sql, exception);
                    }
                    else if (Array.IndexOf(errorCodes.DataAccessResourceFailureCodes, errorCode) >= 0) 
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new DataAccessResourceFailureException(BuildMessage(task, sql, exception), exception);
                    }
                    else if (Array.IndexOf(errorCodes.TransientAccessResourceFailureCodes, errorCode) >= 0)
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new TransientDataAccessResourceException(BuildMessage(task, sql, exception), exception);
                    }
                    else if (Array.IndexOf(errorCodes.PermissionDeniedCodes, errorCode) >= 0) 
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new PermissionDeniedDataAccessException(BuildMessage(task, sql, exception), exception);
                    }
                    else if (Array.IndexOf(errorCodes.DataIntegrityViolationCodes, errorCode) >= 0) 
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new DataIntegrityViolationException(BuildMessage(task, sql, exception), exception);
                    }
                    else if (Array.IndexOf(errorCodes.CannotAcquireLockCodes, errorCode) >= 0) 
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new CannotAcquireLockException(BuildMessage(task, sql, exception), exception);
                    }
                    else if (Array.IndexOf(errorCodes.DeadlockLoserCodes, errorCode) >= 0) 
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new DeadlockLoserDataAccessException(BuildMessage(task, sql, exception), exception);
                    }
                    else if (Array.IndexOf(errorCodes.CannotSerializeTransactionCodes, errorCode) >= 0) 
                    {
                        LogTranslation(task, sql, errorCode, exception, false);
                        return new CannotSerializeTransactionException(BuildMessage(task, sql, exception), exception);
                    }
              }
          }
          return null;
      }

        /// <summary>
        /// Subclasses can override this method to attempt a custom mapping from a data access Exception
        /// to DataAccessException.
        /// </summary>
        /// <param name="task">Readable text describing the task being attempted.</param>
        /// <param name="sql">SQL query or update that caused the problem. May be <code>null</code>.</param>
        /// <param name="errorCode">The error code extracted from the generic data access exception for
        /// a particular provider.</param>
        /// <param name="exception">The exception thrown from a data access operation.</param>
        /// <returns>
        /// null if no custom translation was possible, otherwise a DataAccessException
        /// resulting from custom translation.  This exception should include the exception parameter
        /// as a nested root cause. This implementation always returns null, meaning that
        /// the translator always falls back to the default error codes.
        /// </returns>
      protected virtual DataAccessException TranslateException(string task, string sql, string errorCode, Exception exception)
      {
          return null;
      }


      /// <summary>
      /// Builds the message.
      /// </summary>
      /// <param name="task">The task.</param>
      /// <param name="sql">The SQL.</param>
      /// <param name="exception">The exception.</param>
      /// <returns></returns>
      protected virtual string BuildMessage(string task, string sql, Exception exception)
      {
          return task + "; SQL [" + sql + "]; " + exception.Message;
      }

      /// <summary>
        /// Determines whether the specified exception is valid data access exception.
        /// </summary>
        /// <param name="e">The exception.</param>
        /// <returns>
        ///   <c>true</c> if is valid data access exception; otherwise, <c>false</c>.
        /// </returns>
      public bool IsValidDataAccessException(Exception e)
      {
         return dbProvider.IsDataAccessException(e);
        }

        /// <summary>
        /// Logs the translation.
        /// </summary>
        /// <param name="task">The task.</param>
        /// <param name="sql">The SQL.</param>
        /// <param name="errorCode">The error code.</param>
        /// <param name="exception">The exception.</param>
        /// <param name="b">if set to <c>true</c> [b].</param>
      private void LogTranslation(string task, string sql, string errorCode, Exception exception, bool b)
      {
            if (log.IsDebugEnabled) 
            {
                String intro = "Translating";
                log.Debug(intro + " ADO exception with error code '" + errorCode
                          + "', message [" + exception.Message +
                    "]; SQL was [" + sql + "] for task [" + task + "]");
            }
      }

      private string ExtractErrorCode(Exception exception)
      {
            // Use provider specific reflection information to extract error code.
          return dbProvider.ExtractError(exception);
      }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.