ObjectDataSourceView.cs :  » 2.6.4-mono-.net-core » System.Web » System » Web » UI » WebControls » 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 » 2.6.4 mono .net core » System.Web 
System.Web » System » Web » UI » WebControls » ObjectDataSourceView.cs
//
// System.Web.UI.WebControls.ObjectDataSourceView
//
// Authors:
//  Lluis Sanchez Gual (lluis@novell.com)
//
// (C) 2005 Novell, Inc. (http://www.novell.com)
//

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#if NET_2_0
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Data;
using System.Web.Compilation;

namespace System.Web.UI.WebControls{

  public class ObjectDataSourceView : DataSourceView, IStateManager
  {
    ObjectDataSource owner;
    HttpContext context;
    Type objectType;
    Type dataObjectType;

    bool convertNullToDBNull = false;
    bool enablePaging = false;
    string dataObjectTypeName = null;
    string filterExpression = null;
    string maximumRowsParameterName = null;
    string oldValuesParameterFormatString = null;
    string deleteMethod = null;
    string insertMethod = null;
    string selectCountMethod = null;
    string selectMethod = null;
    string sortParameterName = null;
    string startRowIndexParameterName = null;
    string typeName = null;
    string updateMethod = null;

    bool isTrackingViewState = false;
    ParameterCollection selectParameters;
    ParameterCollection updateParameters;
    ParameterCollection deleteParameters;
    ParameterCollection insertParameters;
    ParameterCollection filterParameters;
    
    static readonly object DeletedEvent = new object();
    static readonly object DeletingEvent = new object();
    static readonly object FilteringEvent = new object();
    static readonly object InsertedEvent = new object();
    static readonly object InsertingEvent = new object();
    static readonly object ObjectCreatedEvent = new object();
    static readonly object ObjectCreatingEvent = new object();
    static readonly object ObjectDisposingEvent = new object();
    //    static readonly object ResolvingMethodEvent = new object();
    static readonly object SelectedEvent = new object();
    static readonly object SelectingEvent = new object();
    static readonly object UpdatedEvent = new object();
    static readonly object UpdatingEvent = new object();
    
    public ObjectDataSourceView (ObjectDataSource owner, string name, HttpContext context): base (owner, name)
    {
      this.owner = owner;
      this.context = context;
    }
    
    public event ObjectDataSourceStatusEventHandler Deleted {
      add { Events.AddHandler (DeletedEvent, value); }
      remove { Events.RemoveHandler (DeletedEvent, value); }
    }
    
    public event ObjectDataSourceMethodEventHandler Deleting {
      add { Events.AddHandler (DeletingEvent, value); }
      remove { Events.RemoveHandler (DeletingEvent, value); }
    }
    
    public event ObjectDataSourceFilteringEventHandler Filtering {
      add { Events.AddHandler (FilteringEvent, value); }
      remove { Events.RemoveHandler (FilteringEvent, value); }
    }
    
    public event ObjectDataSourceStatusEventHandler Inserted {
      add { Events.AddHandler (InsertedEvent, value); }
      remove { Events.RemoveHandler (InsertedEvent, value); }
    }
    
    public event ObjectDataSourceMethodEventHandler Inserting {
      add { Events.AddHandler (InsertingEvent, value); }
      remove { Events.RemoveHandler (InsertingEvent, value); }
    }
    
    public event ObjectDataSourceObjectEventHandler ObjectCreated {
      add { Events.AddHandler (ObjectCreatedEvent, value); }
      remove { Events.RemoveHandler (ObjectCreatedEvent, value); }
    }
    
    public event ObjectDataSourceObjectEventHandler ObjectCreating {
      add { Events.AddHandler (ObjectCreatingEvent, value); }
      remove { Events.RemoveHandler (ObjectCreatingEvent, value); }
    }
    
    public event ObjectDataSourceDisposingEventHandler ObjectDisposing {
      add { Events.AddHandler (ObjectDisposingEvent, value); }
      remove { Events.RemoveHandler (ObjectDisposingEvent, value); }
    }
    
    /*    public event ObjectDataSourceResolvingMethodEventHandler ResolvingMethod {
        add { Events.AddHandler (ResolvingMethodEvent, value); }
        remove { Events.RemoveHandler (ResolvingMethodEvent, value); }
        }
    */
    public event ObjectDataSourceStatusEventHandler Selected {
      add { Events.AddHandler (SelectedEvent, value); }
      remove { Events.RemoveHandler (SelectedEvent, value); }
    }
    
    public event ObjectDataSourceSelectingEventHandler Selecting {
      add { Events.AddHandler (SelectingEvent, value); }
      remove { Events.RemoveHandler (SelectingEvent, value); }
    }
    
    public event ObjectDataSourceStatusEventHandler Updated {
      add { Events.AddHandler (UpdatedEvent, value); }
      remove { Events.RemoveHandler (UpdatedEvent, value); }
    }
    
    public event ObjectDataSourceMethodEventHandler Updating {
      add { Events.AddHandler (UpdatingEvent, value); }
      remove { Events.RemoveHandler (UpdatingEvent, value); }
    }
    
    protected virtual void OnDeleted (ObjectDataSourceStatusEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [DeletedEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnDeleting (ObjectDataSourceMethodEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [DeletingEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnFiltering (ObjectDataSourceFilteringEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceFilteringEventHandler eh = (ObjectDataSourceFilteringEventHandler) Events [FilteringEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnInserted (ObjectDataSourceStatusEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [InsertedEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnInserting (ObjectDataSourceMethodEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [InsertingEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnObjectCreated (ObjectDataSourceEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceObjectEventHandler eh = (ObjectDataSourceObjectEventHandler) Events [ObjectCreatedEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnObjectCreating (ObjectDataSourceEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceObjectEventHandler eh = (ObjectDataSourceObjectEventHandler) Events [ObjectCreatingEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnObjectDisposing (ObjectDataSourceDisposingEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceDisposingEventHandler eh = (ObjectDataSourceDisposingEventHandler) Events [ObjectDisposingEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    /*    protected virtual void OnResolvingMethod (ObjectDataSourceResolvingMethodEventArgs e)
        {
        if (Events != null) {
        ObjectDataSourceResolvingMethodEventHandler eh = (ObjectDataSourceResolvingMethodEventHandler) Events [ResolvingMethodEvent];
        if (eh != null) eh (this, e);
        }
        }
    */
    
    protected virtual void OnSelected (ObjectDataSourceStatusEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [SelectedEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnSelecting (ObjectDataSourceSelectingEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceSelectingEventHandler eh = (ObjectDataSourceSelectingEventHandler) Events [SelectingEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnUpdated (ObjectDataSourceStatusEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [UpdatedEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnUpdating (ObjectDataSourceMethodEventArgs e)
    {
      if (Events != null) {
        ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [UpdatingEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    public override bool CanDelete {
      get { return DeleteMethod.Length > 0; }
    }
    
    public override bool CanInsert {
      get { return InsertMethod.Length > 0; }
    }
    
    public override bool CanPage {
      get { return EnablePaging; }
    }
    
    public override bool CanRetrieveTotalRowCount {
      get {
        if( SelectCountMethod.Length > 0)
          return true;

        return !EnablePaging;
      }
    }
    
    public override bool CanSort {
      get { return true; }
    }
    
    public override bool CanUpdate {
      get { return UpdateMethod.Length > 0; }
    }

    // LAME SPEC: MSDN says value should be stored in ViewState but tests show otherwise.
    ConflictOptions conflictDetection = ConflictOptions.OverwriteChanges;
    public ConflictOptions ConflictDetection {
      get { return conflictDetection; }
      set {
        if (ConflictDetection == value)
          return;
        conflictDetection = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public bool ConvertNullToDBNull  {
      get { return convertNullToDBNull; }
      set { convertNullToDBNull = value; }
    }

    public string DataObjectTypeName {
      get {
        return dataObjectTypeName != null ? dataObjectTypeName : string.Empty;
      }
      set {
        if (DataObjectTypeName == value)
          return;
        dataObjectTypeName = value;
        dataObjectType = null;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public string DeleteMethod {
      get {
        return deleteMethod != null ? deleteMethod : string.Empty;
      }
      set {
        deleteMethod = value;
      }
    }
    
    public ParameterCollection DeleteParameters {
      get {
        if (deleteParameters == null) {
          deleteParameters = new ParameterCollection ();
        }
        return deleteParameters;
      }
    }

    public bool EnablePaging {
      get {
        return enablePaging;
      }
      set {
        if (EnablePaging == value)
          return;
        enablePaging = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public string FilterExpression {
      get {
        return filterExpression != null ? filterExpression : string.Empty;
      }
      set {
        if (FilterExpression == value)
          return;
        filterExpression = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public ParameterCollection FilterParameters {
      get {
        if (filterParameters == null) {
          filterParameters = new ParameterCollection ();
          filterParameters.ParametersChanged += new EventHandler (OnParametersChanged); 
          if (IsTrackingViewState)
            ((IStateManager)filterParameters).TrackViewState ();
        }
        return filterParameters;
      }
    }

    public string InsertMethod {
      get {
        return insertMethod != null ? insertMethod : string.Empty;
      }
      set {
        insertMethod = value;
      }
    }

    public ParameterCollection InsertParameters {
      get {
        if (insertParameters == null) {
          insertParameters = new ParameterCollection ();
        }
        return insertParameters;
      }
    }

    public string MaximumRowsParameterName {
      get {
        return maximumRowsParameterName != null ? maximumRowsParameterName : "maximumRows";
      }
      set {
        if (MaximumRowsParameterName == value)
          return;
        maximumRowsParameterName = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public string OldValuesParameterFormatString {
      get {
        return oldValuesParameterFormatString != null ? oldValuesParameterFormatString : "{0}";
      }
      set {
        if (OldValuesParameterFormatString == value)
          return;
        oldValuesParameterFormatString = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public string SelectCountMethod {
      get {
        return selectCountMethod != null ? selectCountMethod : string.Empty;
      }
      set {
        if (SelectCountMethod == value)
          return;
        selectCountMethod = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public string SelectMethod {
      get {
        return selectMethod != null ? selectMethod : string.Empty;
      }
      set {
        if (SelectMethod == value)
          return;
        selectMethod = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public ParameterCollection SelectParameters {
      get {
        if (selectParameters == null) {
          selectParameters = new ParameterCollection ();
          selectParameters.ParametersChanged += new EventHandler (OnParametersChanged); 
          if (IsTrackingViewState)
            ((IStateManager)selectParameters).TrackViewState ();
        }
        return selectParameters;
      }
    }

    public string SortParameterName {
      get {
        return sortParameterName != null ? sortParameterName : string.Empty;
      }
      set {
        sortParameterName = value;
      }
    }

    public string StartRowIndexParameterName {
      get {
        return startRowIndexParameterName != null ? startRowIndexParameterName : "startRowIndex";
      }
      set {
        if (StartRowIndexParameterName == value)
          return;
        startRowIndexParameterName = value;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public string TypeName {
      get {
        return typeName != null ? typeName : string.Empty;
      }
      set {
        if (TypeName == value)
          return;
        typeName = value;
        objectType = null;
        OnDataSourceViewChanged (EventArgs.Empty);
      }
    }

    public string UpdateMethod {
      get {
        return updateMethod != null ? updateMethod : string.Empty;
      }
      set {
        updateMethod = value;
      }
    }

    public ParameterCollection UpdateParameters {
      get {
        if (updateParameters == null) {
          updateParameters = new ParameterCollection ();
        }
        return updateParameters;
      }
    }
    
    Type ObjectType {
      get {
        if (objectType == null) {
          objectType = HttpApplication.LoadType (TypeName);
          if (objectType == null)
            throw new InvalidOperationException ("Type not found: " + TypeName);
        }
        return objectType;
      }
    }
    
    Type DataObjectType {
      get {
        if (dataObjectType == null) {
          dataObjectType = HttpApplication.LoadType (DataObjectTypeName);
          if (dataObjectType == null)
            throw new InvalidOperationException ("Type not found: " + DataObjectTypeName);
        }
        return dataObjectType;
      }
    }
    
    public IEnumerable Select (DataSourceSelectArguments arguments)
    {
      return ExecuteSelect (arguments);
    }
    
    public int Update (IDictionary keys, IDictionary values, IDictionary oldValues)
    {
      return ExecuteUpdate (keys, values, oldValues);
    }
    
    public int Delete (IDictionary keys, IDictionary oldValues)
    {
      return ExecuteDelete (keys, oldValues);
    }
    
    public int Insert (IDictionary values)
    {
      return ExecuteInsert (values);
    }
    
    protected override int ExecuteInsert (IDictionary values)
    {
      if (!CanInsert)
        throw new NotSupportedException ("Insert operation not supported.");
        
      IOrderedDictionary paramValues;
      MethodInfo method;
      
      if (DataObjectTypeName.Length == 0) {
        paramValues = MergeParameterValues (InsertParameters, values, null);
        method = GetObjectMethod (InsertMethod, paramValues, DataObjectMethodType.Insert);
      } else {
        method = ResolveDataObjectMethod (InsertMethod, values, null, out paramValues);
      }
      
      ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
      OnInserting (args);
      if (args.Cancel)
        return -1;
      
      ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
      OnInserted (rargs);
      
      if (rargs.Exception != null && !rargs.ExceptionHandled)
        throw rargs.Exception;

      if (owner.EnableCaching)
        owner.Cache.Expire ();
      
      OnDataSourceViewChanged (EventArgs.Empty);

      return -1;
    }

    protected override int ExecuteDelete (IDictionary keys, IDictionary oldValues)
    {
      if (!CanDelete)
        throw new NotSupportedException ("Delete operation not supported.");
        
      if (ConflictDetection == ConflictOptions.CompareAllValues && (oldValues == null || oldValues.Count == 0))
        throw new InvalidOperationException ("ConflictDetection is set to CompareAllValues and oldValues collection is null or empty.");

      IDictionary oldDataValues;
      oldDataValues = BuildOldValuesList (keys, oldValues, false);
          
      IOrderedDictionary paramValues;
      MethodInfo method;
      
      if (DataObjectTypeName.Length == 0) {
        paramValues = MergeParameterValues (DeleteParameters, null, oldDataValues);
        method = GetObjectMethod (DeleteMethod, paramValues, DataObjectMethodType.Delete);
      } else {
        method = ResolveDataObjectMethod (DeleteMethod, oldDataValues, null, out paramValues);
      }
      
      ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
      OnDeleting (args);
      if (args.Cancel)
        return -1;
      
      ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
      
      OnDeleted (rargs);
      
      if (rargs.Exception != null && !rargs.ExceptionHandled)
        throw rargs.Exception;

      if (owner.EnableCaching)
        owner.Cache.Expire ();
      
      OnDataSourceViewChanged (EventArgs.Empty);

      return -1;
    }

    protected override int ExecuteUpdate (IDictionary keys, IDictionary values, IDictionary oldValues)
    {
      IOrderedDictionary paramValues;
      MethodInfo method;

      IDictionary oldDataValues;
      oldDataValues = BuildOldValuesList (keys, oldValues, true);

      if (DataObjectTypeName.Length == 0)
      {
        IDictionary dataValues;
        dataValues = values;
        paramValues = MergeParameterValues (UpdateParameters, dataValues, oldDataValues);
        method = GetObjectMethod (UpdateMethod, paramValues, DataObjectMethodType.Update);
      }
      else
      {
        if (ConflictDetection != ConflictOptions.CompareAllValues) {
          oldDataValues = null;
        }
        IDictionary dataValues = new Hashtable ();
        if (keys != null) {
          foreach (DictionaryEntry de in keys)
            dataValues [de.Key] = de.Value;
        }
        if (values != null) {
          foreach (DictionaryEntry de in values)
            dataValues [de.Key] = de.Value;
        }

        method = ResolveDataObjectMethod (UpdateMethod, dataValues, oldDataValues, out paramValues);
      }      

      ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
      OnUpdating (args);
      if (args.Cancel)
        return -1;
      
      ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
      OnUpdated (rargs);
      
      if (rargs.Exception != null && !rargs.ExceptionHandled)
        throw rargs.Exception;

      if (owner.EnableCaching)
        owner.Cache.Expire ();
      
      OnDataSourceViewChanged (EventArgs.Empty);

      return -1;
    }

    IDictionary BuildOldValuesList (IDictionary keys, IDictionary oldValues, bool keysWin) 
    {
      IDictionary oldDataValues;
      if (ConflictDetection == ConflictOptions.CompareAllValues) {
        oldDataValues = new Hashtable ();
        if (keys != null && !keysWin) {
          foreach (DictionaryEntry de in keys)
            oldDataValues [de.Key] = de.Value;
        }
        if (oldValues != null) {
          foreach (DictionaryEntry de in oldValues)
            oldDataValues [de.Key] = de.Value;
        }
        if (keys != null && keysWin) {
          foreach (DictionaryEntry de in keys)
            oldDataValues [de.Key] = de.Value;
        }
      }
      else {
        oldDataValues = keys;
      }

      return oldDataValues;
    }

    protected internal override IEnumerable ExecuteSelect (DataSourceSelectArguments arguments)
    {
      arguments.RaiseUnsupportedCapabilitiesError (this);

      IOrderedDictionary paramValues = MergeParameterValues (SelectParameters, null, null);
      ObjectDataSourceSelectingEventArgs args = new ObjectDataSourceSelectingEventArgs (paramValues, arguments, false);

      object result = null;

      if (owner.EnableCaching)
        result = owner.Cache.GetCachedObject (SelectMethod, SelectParameters);

      if (result == null) {
        OnSelecting (args);
        if (args.Cancel)
          return new ArrayList ();
        
        if (CanPage) {
          if (StartRowIndexParameterName.Length == 0)
            throw new InvalidOperationException ("Paging is enabled, but the StartRowIndexParameterName property is not set.");
          if (MaximumRowsParameterName.Length == 0)
            throw new InvalidOperationException ("Paging is enabled, but the MaximumRowsParameterName property is not set.");
          paramValues [StartRowIndexParameterName] = arguments.StartRowIndex;
          paramValues [MaximumRowsParameterName] = arguments.MaximumRows;
        }

        if (SortParameterName.Length > 0)
          paramValues [SortParameterName] = arguments.SortExpression;

        result = InvokeSelect (SelectMethod, paramValues);

        if (CanRetrieveTotalRowCount && arguments.RetrieveTotalRowCount)
          arguments.TotalRowCount = QueryTotalRowCount (MergeParameterValues (SelectParameters, null, null), arguments);
        
        if (owner.EnableCaching)
          owner.Cache.SetCachedObject (SelectMethod, SelectParameters, result);
      }

      if (FilterExpression.Length > 0 && !(result is DataGrid || result is DataView || result is DataTable))
        throw new NotSupportedException ("The FilterExpression property was set and the Select method does not return a DataSet, DataTable, or DataView.");

      if (owner.EnableCaching && result is IDataReader)
        throw new NotSupportedException ("Data source does not support caching objects that implement IDataReader");
      
      if (result is DataSet) {
        DataSet dset = (DataSet) result;
        if (dset.Tables.Count == 0)
          throw new InvalidOperationException ("The select method returnet a DataSet which doesn't contain any table.");
        result = dset.Tables [0];
      }
      
      if (result is DataTable) {
        DataView dview = new DataView ((DataTable)result);
        if (arguments.SortExpression != null && arguments.SortExpression.Length > 0) {
          dview.Sort = arguments.SortExpression;
        }
        if (FilterExpression.Length > 0) {
          IOrderedDictionary fparams = FilterParameters.GetValues (context, owner);
          ObjectDataSourceFilteringEventArgs fargs = new ObjectDataSourceFilteringEventArgs (fparams);
          OnFiltering (fargs);
          if (!fargs.Cancel) {
            object[] formatValues = new object [fparams.Count];
            for (int n=0; n<formatValues.Length; n++) {
              formatValues [n] = fparams [n];
              if (formatValues [n] == null) return dview;
            }
            dview.RowFilter = string.Format  (FilterExpression, formatValues);
          }
        }
        return dview;
      }
      
      if (result is IEnumerable)
        return (IEnumerable) result;
      else
        return new object[] {result};
    }
    
    int QueryTotalRowCount (IOrderedDictionary mergedParameters, DataSourceSelectArguments arguments)
    {
      ObjectDataSourceSelectingEventArgs countArgs = new ObjectDataSourceSelectingEventArgs (mergedParameters, arguments, true);
      OnSelecting (countArgs);
      if (countArgs.Cancel)
        return 0;
      
      object count = InvokeSelect (SelectCountMethod, mergedParameters);
      return (int) Convert.ChangeType (count, typeof(int));
    }
    
    object InvokeSelect (string methodName, IOrderedDictionary paramValues)
    {
      MethodInfo method = GetObjectMethod (methodName, paramValues, DataObjectMethodType.Select);
      ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
      OnSelected (rargs);
      
      if (rargs.Exception != null && !rargs.ExceptionHandled)
        throw rargs.Exception;

      return rargs.ReturnValue;
    }
    
    ObjectDataSourceStatusEventArgs InvokeMethod (MethodInfo method, IOrderedDictionary paramValues)
    {
      object instance = null;

      if (!method.IsStatic)
        instance = CreateObjectInstance ();

      ParameterInfo[] pars = method.GetParameters ();
      
      ArrayList outParamInfos;
      object[] methodArgs = GetParameterArray (pars, paramValues, out outParamInfos); 
      
      if (methodArgs == null)
        throw CreateMethodException (method.Name, paramValues);
          
      object result = null;
      Hashtable outParams = null;
      
      try {
        result = method.Invoke (instance, methodArgs);
        if (outParamInfos != null) {
          outParams = new Hashtable ();
          foreach (ParameterInfo op in outParamInfos)
            outParams [op.Name] = methodArgs [op.Position];
        }
        return new ObjectDataSourceStatusEventArgs (result, outParams, null);
      }
      catch (Exception ex) {
        return new ObjectDataSourceStatusEventArgs (result, outParams, ex);
      }
      finally {
        if (instance != null)
          DisposeObjectInstance (instance);
      }
    }
    
    MethodInfo GetObjectMethod (string methodName, IOrderedDictionary parameters, DataObjectMethodType methodType)
    {
      MemberInfo[] methods = ObjectType.GetMember (methodName, MemberTypes.Method, BindingFlags.Instance | 
                     BindingFlags.Static | 
                     BindingFlags.Public | 
                     BindingFlags.IgnoreCase |
                     BindingFlags.FlattenHierarchy);
      if (methods.Length > 1) {
        // MSDN: The ObjectDataSource resolves method overloads by method name and number
        // of parameters; the names and types of the parameters are not considered.
        // LAMESPEC: the tests show otherwise
        DataObjectMethodAttribute methodAttribute = null;
        MethodInfo methodInfo = null;
        bool hasConflict = false;
        foreach (MethodInfo me in methods) { // we look for methods only
          ParameterInfo [] pinfos = me.GetParameters ();
          if (pinfos.Length == parameters.Count) {
            object [] attrs = me.GetCustomAttributes (typeof (DataObjectMethodAttribute), true);
            DataObjectMethodAttribute domAttr = (attrs != null && attrs.Length > 0) ? (DataObjectMethodAttribute) attrs [0] : null;
            if (domAttr != null && domAttr.MethodType != methodType)
              continue;

            bool paramsMatch = true;
            foreach (ParameterInfo pinfo in pinfos) {
              if (!parameters.Contains (pinfo.Name)) {
                paramsMatch = false;
                break;
              }
            }

            if (!paramsMatch)
              continue;

            if (domAttr != null) {
              if (methodAttribute != null) {
                if (methodAttribute.IsDefault) {
                  if (domAttr.IsDefault) {
                    methodInfo = null;
                    break; //fail due to a conflict
                  }
                  else
                    continue; //existing matches better
                }
                else {
                  methodInfo = null; //we override
                  hasConflict = !domAttr.IsDefault;
                }
              }
              else
                methodInfo = null; //we override
            }

            if (methodInfo == null) {
              methodAttribute = domAttr;
              methodInfo = me;
              continue;
            }

            hasConflict = true;
          }
        }

        if (!hasConflict && methodInfo != null)
          return methodInfo;
      }
      else if (methods.Length == 1) {
        MethodInfo me = methods[0] as MethodInfo;
        if (me != null && me.GetParameters().Length == parameters.Count)
          return me;
      }
      
      throw CreateMethodException (methodName, parameters);
    }
    
    MethodInfo ResolveDataObjectMethod (string methodName, IDictionary values, IDictionary oldValues, out IOrderedDictionary paramValues)
    {
      MethodInfo method;
      if (oldValues != null)
        method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType, DataObjectType });
      else
        method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType });
      
      if (method == null)
        throw new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters of type '" + DataObjectType + "' in '" + ObjectType + "'.");

      paramValues = new OrderedDictionary (StringComparer.InvariantCultureIgnoreCase);
      ParameterInfo[] ps = method.GetParameters ();
      
      if (oldValues != null) {
        if (FormatOldParameter (ps[0].Name) == ps[1].Name) {
          paramValues [ps[0].Name] = CreateDataObject (values);
          paramValues [ps[1].Name] = CreateDataObject (oldValues);
        } else if (FormatOldParameter (ps[1].Name) == ps[0].Name) {
          paramValues [ps[0].Name] = CreateDataObject (oldValues);
          paramValues [ps[1].Name] = CreateDataObject (values);
        } else
          throw new InvalidOperationException ("Method '" + methodName + "' does not have any parameter that fits the value of OldValuesParameterFormatString.");  
      } else {
        paramValues [ps[0].Name] = CreateDataObject (values);
      }
      return method;
    }
    
    Exception CreateMethodException (string methodName, IOrderedDictionary parameters)
    {
      string s = "";
      foreach (string p in parameters.Keys) {
        s += p + ", ";
      }
      return new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters " + s + "in type '" + ObjectType + "'.");
    }
    
    object CreateDataObject (IDictionary values)
    {
      object ob = Activator.CreateInstance (DataObjectType);
      foreach (DictionaryEntry de in values) {
        PropertyInfo p = DataObjectType.GetProperty ((string)de.Key);
        if (p == null) throw new InvalidOperationException ("Property " + de.Key + " not found in type '" +DataObjectType + "'.");
        object[] attributes = p.GetCustomAttributes (typeof (System.ComponentModel.TypeConverterAttribute),
                       true);
        Type propertyType = p.PropertyType;
        object value = de.Value;
        object converted = ConvertParameterWithTypeConverter (attributes, propertyType, value);
        if (converted == null)
          converted = ConvertParameter (propertyType, value);
               
        p.SetValue (ob, converted, null);
      }
      return ob;
    }
    
    object CreateObjectInstance ()
    {
      ObjectDataSourceEventArgs args = new ObjectDataSourceEventArgs (null);
      OnObjectCreating (args);
      
      if (args.ObjectInstance != null)
        return args.ObjectInstance;
        
      object ob = Activator.CreateInstance (ObjectType);
      
      args.ObjectInstance = ob;
      OnObjectCreated (args);
      
      return args.ObjectInstance;
    }
    
    void DisposeObjectInstance (object obj)
    {
      ObjectDataSourceDisposingEventArgs args = new ObjectDataSourceDisposingEventArgs (obj);
      OnObjectDisposing (args);
      
      if (!args.Cancel) {
        IDisposable disp = obj as IDisposable;
        if (disp != null) disp.Dispose ();
      }
    }

    object FindValueByName (string name, IDictionary values, bool format)
    {
      if (values == null)
        return null;

      foreach (DictionaryEntry de in values) {
        string valueName = format == true ? FormatOldParameter (de.Key.ToString ()) : de.Key.ToString ();
        if (String.Compare (name, valueName, StringComparison.InvariantCultureIgnoreCase) == 0)
          return values [de.Key];
      }
      return null;
    }

    /// <summary>
    /// Merge the current data item fields with view parameter default values
    /// </summary>
    /// <param name="viewParams">default parameters</param>
    /// <param name="values">new parameters for update and insert</param>
    /// <param name="oldValues">old parameters for update and delete</param>
    /// <param name="allwaysAddNewValues">true for insert, as current item is
    /// irrelevant for insert</param>
    /// <returns>merged values</returns>
    IOrderedDictionary MergeParameterValues (ParameterCollection viewParams, IDictionary values, IDictionary oldValues)
    {
      IOrderedDictionary parametersValues = viewParams.GetValues (context, owner);
      OrderedDictionary mergedValues = new OrderedDictionary (StringComparer.InvariantCultureIgnoreCase);
      foreach (string parameterName in parametersValues.Keys) {
        mergedValues [parameterName] = parametersValues [parameterName];
        if (oldValues != null) {
          object value = FindValueByName (parameterName, oldValues, true);
          if (value != null) {
            object dataValue = viewParams [parameterName].ConvertValue (value);
            mergedValues [parameterName] = dataValue;
          }
        }

        if (values != null) {
          object value = FindValueByName (parameterName, values, false);
          if (value != null) {
            object dataValue = viewParams [parameterName].ConvertValue (value);
            mergedValues [parameterName] = dataValue;
          }
        }
      }

      if (values != null) {
        foreach (DictionaryEntry de in values)
          if (FindValueByName ((string) de.Key, mergedValues, false) == null)
            mergedValues [de.Key] = de.Value;
      }

      if (oldValues != null) {
        foreach (DictionaryEntry de in oldValues) {
          string oldValueKey = FormatOldParameter ((string) de.Key);
          if (FindValueByName (oldValueKey, mergedValues, false) == null)
            mergedValues [oldValueKey] = de.Value;
        }
      }

      return mergedValues;
    }
    
    object[] GetParameterArray (ParameterInfo[] methodParams, IOrderedDictionary viewParams, out ArrayList outParamInfos)
    {
      // FIXME: make this case insensitive

      outParamInfos = null;
      object[] values = new object [methodParams.Length];
      
      foreach (ParameterInfo mp in methodParams) {
      
        // Parameter names must match
        if (!viewParams.Contains (mp.Name)) return null;
        
        values [mp.Position] = ConvertParameter (mp.ParameterType, viewParams [mp.Name]);
        if (mp.ParameterType.IsByRef) {
          if (outParamInfos == null) outParamInfos = new ArrayList ();
          outParamInfos.Add (mp);
        }
      }
      return values;
    }

    object ConvertParameterWithTypeConverter (object[] attributes, Type targetType, object value)
    {
      if (attributes == null || attributes.Length == 0 || value == null)
        return null;
      TypeConverterAttribute tca;
      Type converterType;
      TypeConverter converter;
      
      foreach (object a in attributes) {
        tca = a as TypeConverterAttribute;
        if (tca == null)
          continue;
        converterType = HttpApplication.LoadType (tca.ConverterTypeName, false);
        if (converterType == null)
          continue;
        converter = Activator.CreateInstance (converterType, new object[] {targetType}) as TypeConverter;
        if (converter == null)
          continue;
        if (converter.CanConvertFrom (value.GetType ()))
          return converter.ConvertFrom (value);
        else if (converter.CanConvertFrom (typeof (string)))
          return converter.ConvertFrom (value.ToString ());
      }
      
      return null;
    }
    
    object ConvertParameter (Type targetType, object value)
    {
      return ConvertParameter (Type.GetTypeCode (targetType), value);
    }
    
    object ConvertParameter (TypeCode targetType, object value)
    {
      if (value == null) {
        if (targetType != TypeCode.Object && targetType != TypeCode.String)
          value = 0;
        else if (ConvertNullToDBNull)
          return DBNull.Value;
      }
      if (targetType == TypeCode.Object || targetType == TypeCode.Empty)
        return value;
      else
        return Convert.ChangeType (value, targetType);
    }
    
    string FormatOldParameter (string name)
    {
      string f = OldValuesParameterFormatString;
      if (f.Length > 0)
        return String.Format (f, name);
      else
        return name;
    }
    
    void OnParametersChanged (object sender, EventArgs args)
    {
      OnDataSourceViewChanged (EventArgs.Empty);
    }
    
    protected virtual void LoadViewState (object savedState)
    {
      object[] state = (savedState == null) ? new object [5] : (object[]) savedState;
      ((IStateManager)SelectParameters).LoadViewState (state[0]); 
      ((IStateManager)UpdateParameters).LoadViewState (state[1]); 
      ((IStateManager)DeleteParameters).LoadViewState (state[2]); 
      ((IStateManager)InsertParameters).LoadViewState (state[3]); 
      ((IStateManager)FilterParameters).LoadViewState (state[4]); 
    }

    protected virtual object SaveViewState()
    {
      object[] state = new object [5];
      
      if (selectParameters != null)
        state [0] = ((IStateManager)selectParameters).SaveViewState ();
      if (updateParameters != null)
        state [1] = ((IStateManager)updateParameters).SaveViewState ();
      if (deleteParameters != null)
        state [2] = ((IStateManager)deleteParameters).SaveViewState ();
      if (insertParameters != null)
        state [3] = ((IStateManager)insertParameters).SaveViewState ();
      if (filterParameters != null)
        state [4] = ((IStateManager)filterParameters).SaveViewState ();
      
      foreach (object ob in state)
        if (ob != null) return state;
      
      return null;
    }
    
    protected virtual void TrackViewState()
    {
      isTrackingViewState = true;

      if (selectParameters != null) ((IStateManager)selectParameters).TrackViewState ();
      if (filterParameters != null) ((IStateManager)filterParameters).TrackViewState ();
    }
    
    protected bool IsTrackingViewState
    {
      get { return isTrackingViewState; }
    }
    
    
    bool IStateManager.IsTrackingViewState
    {
      get { return IsTrackingViewState; }
    }
    
    void IStateManager.TrackViewState()
    {
      TrackViewState ();
    }
    
    void IStateManager.LoadViewState (object savedState)
    {
      LoadViewState (savedState);
    }

    object IStateManager.SaveViewState()
    {
      return SaveViewState ();
    }
  }
}
#endif





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