// Copyright ?2004, 2018, Oracle and/or its affiliates. All rights reserved. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License, version 2.0, as // published by the Free Software Foundation. // // This program is also distributed with certain software (including // but not limited to OpenSSL) that is licensed under separate terms, // as designated in a particular file or component or in included license // documentation. The authors of MySQL hereby grant you an // additional permission to link the program and your derivative works // with the separately licensed software that they have included with // MySQL. // // Without limiting anything contained in the foregoing, this file, // which is part of MySQL Connector/NET, is also subject to the // Universal FOSS Exception, version 1.0, a copy of which can be found at // http://oss.oracle.com/licenses/universal-foss-exception. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License, version 2.0, for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA using System; using System.Collections.Generic; using System.Linq; using MySql.Data.MySqlClient; using Sog.Properties; namespace MySql.Data.MySqlClient.Interceptors { /// /// BaseExceptionInterceptor is the base class that should be used for all userland /// exception interceptors. /// public abstract class BaseExceptionInterceptor { /// /// Returns the received exception. /// /// The exception to be returned. /// The exception originally received. public abstract Exception InterceptException(Exception exception); /// /// Gets the active connection. /// protected MySqlConnection ActiveConnection { get; private set; } /// /// Initilizes this object by setting the active connection. /// /// The connection to become active. public virtual void Init(MySqlConnection connection) { this.ActiveConnection = connection; } } /// /// StandardExceptionInterceptor is the standard interceptor that simply returns the exception. /// It is the default action. /// internal sealed class StandardExceptionInterceptor : BaseExceptionInterceptor { /// /// Returns the received exception, which is the default action /// /// The exception to be returned. /// The exception originally received. public override Exception InterceptException(Exception exception) { return exception; } } /// /// ExceptionInterceptor is the "manager" class that keeps the list of registered interceptors /// for the given connection. /// internal sealed class ExceptionInterceptor : Interceptor { readonly List _interceptors = new List(); public ExceptionInterceptor(MySqlConnection connection) { this.Connection = connection; this.LoadInterceptors(connection.Settings.ExceptionInterceptors); // we always have the standard interceptor this._interceptors.Add(new StandardExceptionInterceptor()); } protected override void AddInterceptor(object o) { if (o == null) { throw new ArgumentException("Unable to instantiate ExceptionInterceptor"); } if (!(o is BaseExceptionInterceptor)) { throw new InvalidOperationException(String.Format( Resources.TypeIsNotExceptionInterceptor, o.GetType())); } BaseExceptionInterceptor ie = o as BaseExceptionInterceptor; ie.Init(this.Connection); this._interceptors.Insert(0, (BaseExceptionInterceptor)o); } public void Throw(Exception exception) { Exception e = this._interceptors.Aggregate(exception, (current, ie) => ie.InterceptException(current)); throw e; } #if !NETCOREAPP protected override string ResolveType(string nameOrType) { if (MySqlConfiguration.Settings == null || MySqlConfiguration.Settings.ExceptionInterceptors == null) return base.ResolveType(nameOrType); foreach (InterceptorConfigurationElement e in MySqlConfiguration.Settings.ExceptionInterceptors) if (String.Compare(e.Name, nameOrType, true) == 0) return e.Type; return base.ResolveType(nameOrType); } #endif } }