unit uRODataSnapModule; interface uses Classes, Provider, Contnrs, uRODataSnap_Intf, uRODataSnapPublishedProvidersCollection, uRODataSnapBaseAppServer; type TRODataSnapModule = class(TRODataSnapBaseAppServer) private fProviders: TPublishedProviders; fInternalRegisteredProviders:TObjectList; fUseProviders: boolean; procedure SetProviders(const Value: TPublishedProviders); protected function GetProviderByName(const iProviderName:string):TCustomProvider; override; function GetProviderNames:TProviderNames; override; protected procedure Notification(AComponent: TComponent; Operation: TOperation); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure RegisterProvider(iProvider:TCustomProvider; const iName:string); overload; procedure UnRegisterProvider(iProvider:TCustomProvider; const iName:string); overload; procedure RegisterProvider(iProvider:TCustomProvider); overload; procedure UnRegisterProvider(iProvider:TCustomProvider); overload; published property Providers:TPublishedProviders read fProviders write SetProviders; property UseProviders:boolean read fUseProviders write fUseProviders default false; end; implementation uses SysUtils, uRODataSnapRes; { TRODataSnapModule } constructor TRODataSnapModule.Create(AOwner: TComponent); begin fProviders := TPublishedProviders.Create(self); fInternalRegisteredProviders := TObjectList.Create(); fInternalRegisteredProviders.OwnsObjects := False; inherited; end; destructor TRODataSnapModule.Destroy; begin FreeAndNil(fProviders); FreeAndNil(fInternalRegisteredProviders); inherited; end; function TRODataSnapModule.GetProviderByName(const iProviderName: string): TCustomProvider; var lPublishedProvider: TPublishedProvider; lProvider:TCustomProvider; i:integer; begin if UseProviders then begin lPublishedProvider := Providers.GetProviderByName(iProviderName); if not Assigned(lPublishedProvider) then raise Exception.CreateFmt(sProviderNotExported,[iProviderName]); result := lPublishedProvider.Provider; if not Assigned(result) then raise Exception.CreateFmt(sProviderNotExported,[iProviderName]); end else begin result := nil; { find provider on datamodule } for i := 0 to ComponentCount-1 do begin if Components[i] is TCustomProvider then begin lProvider := TCustomProvider(Components[i]); if lProvider.Exported and (lProvider.Name = iProviderName) then begin result := lProvider; Exit; end; end; end; { if not, find it in list of explicitely registered list } for i := 0 to fInternalRegisteredProviders.Count-1 do begin lProvider := (fInternalRegisteredProviders[i] as TCustomProvider); if lProvider.Exported and (lProvider.Name = iProviderName) then begin result := lProvider; Exit; end; end; if not Assigned(result) then raise Exception.CreateFmt(sProviderNotExported,[iProviderName]); end; end; function TRODataSnapModule.GetProviderNames: TProviderNames; var i:integer; begin result := TProviderNames.Create(); if UseProviders then begin for i := 0 to Providers.Count-1 do begin if (Providers[i].Name <> '') and Assigned(Providers[i].Provider) then result.Add(Providers[i].Name); end; end else begin { list providers on form } for i := 0 to ComponentCount-1 do begin if Components[i] is TCustomProvider then with TCustomProvider(Components[i]) do begin if Exported then result.Add(Name); end; end; { list explicitely regsitered providers } for i := 0 to fInternalRegisteredProviders.Count-1 do begin with (fInternalRegisteredProviders[i] as TCustomProvider) do begin if Exported then result.Add(Name); end; end; end; end; procedure TRODataSnapModule.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if Operation = opRemove then begin if (AComponent is TCustomProvider) and Assigned(Providers) then begin Providers.UnlinkProvider(AComponent as TCustomProvider); fInternalRegisteredProviders.Remove(AComponent); end; end; end; procedure TRODataSnapModule.RegisterProvider(iProvider:TCustomProvider; const iName:string); begin if not Assigned(iProvider) then Exit; if not fProviders.ContainsProvider(iProvider) then with fProviders.Add() as TPublishedProvider do begin Provider := iProvider; if iName <> '' then Name := iName; end; if fInternalRegisteredProviders.IndexOf(iProvider) = -1 then fInternalRegisteredProviders.Add(iProvider); end; procedure TRODataSnapModule.UnRegisterProvider(iProvider:TCustomProvider; const iName:string); begin if not Assigned(iProvider) then Exit; fProviders.RemoveProvider(iProvider); fInternalRegisteredProviders.Remove(iProvider); end; procedure TRODataSnapModule.RegisterProvider(iProvider: TCustomProvider); begin RegisterProvider(iProvider,''); end; procedure TRODataSnapModule.UnRegisterProvider(iProvider: TCustomProvider); begin UnRegisterProvider(iProvider,''); end; procedure TRODataSnapModule.SetProviders(const Value: TPublishedProviders); begin fProviders.Assign(Value); end; end.