home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Runimage / Delphi50 / Source / Internet / webbroker.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-08-11  |  6.7 KB  |  251 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Visual Component Library         }
  5. {       Web server application components               }
  6. {                                                       }
  7. {       Copyright (c) 1997,99 Inprise Corporation       }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. {$DENYPACKAGEUNIT}
  12.  
  13. unit WebBroker;
  14.  
  15. interface
  16.  
  17. uses SyncObjs, SysUtils, Classes, Masks, Forms, HTTPApp, Contnrs;
  18.  
  19. type
  20.   TWebApplication = class(TComponent)
  21.   private
  22.     FWebModuleClass: TComponentClass;
  23.     FCriticalSection: TCriticalSection;
  24.     FActiveWebModules: TList;
  25.     FInactiveWebModules: TList;
  26.     FTitle: string;
  27.     FMaxConnections: Integer;
  28.     FCacheConnections: Boolean;
  29.     function GetActiveCount: Integer;
  30.     function GetInactiveCount: Integer;
  31.     procedure SetCacheConnections(Value: Boolean);
  32.     procedure OnExceptionHandler(Sender: TObject; E: Exception);
  33.   protected
  34.     function ActivateWebModule: TDataModule;
  35.     procedure DeactivateWebModule(DataModule: TDataModule);
  36.     procedure DoHandleException(E: Exception); dynamic;
  37.     function HandleRequest(Request: TWebRequest; Response: TWebResponse): Boolean;
  38.   public
  39.     constructor Create(AOwner: TComponent); override;
  40.     destructor Destroy; override;
  41.     // The following is uses the current behaviour of the IDE module manager
  42.     procedure CreateForm(InstanceClass: TComponentClass; var Reference); virtual;
  43.     procedure Initialize; virtual;
  44.     procedure Run; virtual;
  45.     property ActiveCount: Integer read GetActiveCount;
  46.     property CacheConnections: Boolean read FCacheConnections write SetCacheConnections;
  47.     property InactiveCount: Integer read GetInactiveCount;
  48.     property MaxConnections: Integer read FMaxConnections write FMaxConnections;
  49.     property Title: string read FTitle write FTitle;
  50.   end;
  51.  
  52. var
  53.   Application: TWebApplication = nil;
  54.  
  55. implementation
  56.  
  57. uses BrkrConst, Windows;
  58.  
  59. { TWebApplication }
  60.  
  61. procedure DoneVCLApplication;
  62. begin
  63.   with Forms.Application do
  64.   begin
  65.     if Handle <> 0 then ShowOwnedPopups(Handle, False);
  66.     ShowHint := False;
  67.     Destroying;
  68.     DestroyComponents;
  69.   end;
  70.   with Application do
  71.   begin
  72.     Destroying;
  73.     DestroyComponents;
  74.   end;
  75. end;
  76.  
  77. procedure DLLExitProc(Reason: Integer); register;
  78. begin
  79.   if Reason = DLL_PROCESS_DETACH then DoneVCLApplication;
  80. end;
  81.  
  82. constructor TWebApplication.Create(AOwner: TComponent);
  83. begin
  84.   inherited Create(AOwner);
  85.   FCriticalSection := TCriticalSection.Create;
  86.   FActiveWebModules := TList.Create;
  87.   FInactiveWebModules := TList.Create;
  88.   FMaxConnections := 32;
  89.   FCacheConnections := True;
  90.   if IsLibrary then
  91.   begin
  92.     IsMultiThread := True;
  93.     DLLProc := @DLLExitProc;
  94.   end;
  95. end;
  96.  
  97. destructor TWebApplication.Destroy;
  98. begin
  99.   Forms.Application.OnException := nil;
  100.   FCriticalSection.Free;
  101.   FActiveWebModules.Free;
  102.   FInactiveWebModules.Free;
  103.   inherited Destroy;
  104. end;
  105.  
  106. procedure TWebApplication.CreateForm(InstanceClass: TComponentClass;
  107.   var Reference);
  108. begin
  109.   if FWebModuleClass = nil then
  110.     FWebModuleClass := InstanceClass
  111.   else raise Exception.CreateRes(@sOnlyOneDataModuleAllowed);
  112. end;
  113.  
  114. function TWebApplication.ActivateWebModule: TDataModule;
  115. begin
  116.   FCriticalSection.Enter;
  117.   try
  118.     Result := nil;
  119.     if (FMaxConnections > 0) and (FActiveWebModules.Count >= FMaxConnections) then
  120.       raise Exception.CreateRes(@sTooManyActiveConnections);
  121.     if FInactiveWebModules.Count > 0 then
  122.     begin
  123.       Result := FInactiveWebModules[0];
  124.       FInactiveWebModules.Delete(0);
  125.       FActiveWebModules.Add(Result);
  126.     end else if FWebModuleClass <> nil then
  127.     begin
  128.       TComponent(Result) := FWebModuleClass.Create(Self);
  129.       FActiveWebModules.Add(Result);
  130.     end else raise Exception.CreateRes(@sNoDataModulesRegistered);
  131.   finally
  132.     FCriticalSection.Leave;
  133.   end;
  134. end;
  135.  
  136. procedure TWebApplication.DeactivateWebModule(DataModule: TDataModule);
  137. begin
  138.   FCriticalSection.Enter;
  139.   try
  140.     FActiveWebModules.Remove(DataModule);
  141.     if FCacheConnections then
  142.       FInactiveWebModules.Add(DataModule)
  143.     else DataModule.Free;  
  144.   finally
  145.     FCriticalSection.Leave;
  146.   end;
  147. end;
  148.  
  149. procedure TWebApplication.DoHandleException(E: Exception);
  150. begin
  151. end;
  152.  
  153. function TWebApplication.GetActiveCount: Integer;
  154. begin
  155.   FCriticalSection.Enter;
  156.   try
  157.     Result := FActiveWebModules.Count;
  158.   finally
  159.     FCriticalSection.Leave;
  160.   end;
  161. end;
  162.  
  163. function TWebApplication.GetInactiveCount: Integer;
  164. begin
  165.   FCriticalSection.Enter;
  166.   try
  167.     Result := FInactiveWebModules.Count;
  168.   finally
  169.     FCriticalSection.Leave;
  170.   end;
  171. end;
  172.  
  173. type
  174.   TWebDispatcherAccess = class(TCustomWebDispatcher);
  175.  
  176. function TWebApplication.HandleRequest(Request: TWebRequest;
  177.   Response: TWebResponse): Boolean;
  178. var
  179.   DataModule: TDataModule;
  180.   Dispatcher: TCustomWebDispatcher;
  181.   I: Integer;
  182. begin
  183.   Result := False;
  184.   DataModule := ActivateWebModule;
  185.   if DataModule <> nil then
  186.   try
  187.     if DataModule is TCustomWebDispatcher then
  188.       Dispatcher := TCustomWebDispatcher(DataModule)
  189.     else with DataModule do
  190.     begin
  191.       Dispatcher := nil;
  192.       for I := 0 to ComponentCount - 1 do
  193.       begin
  194.         if Components[I] is TCustomWebDispatcher then
  195.         begin
  196.           Dispatcher := TCustomWebDispatcher(Components[I]);
  197.           Break;
  198.         end;
  199.       end;
  200.     end;
  201.     if Dispatcher <> nil then
  202.     begin
  203.       Result := TWebDispatcherAccess(Dispatcher).DispatchAction(Request, Response);
  204.       if Result and not Response.Sent then
  205.         Response.SendResponse;
  206.     end else raise Exception.CreateRes(@sNoDispatcherComponent);
  207.   finally
  208.     DeactivateWebModule(DataModule);
  209.   end;
  210. end;
  211.  
  212. procedure TWebApplication.Initialize;
  213. begin
  214.   // This is a place holder
  215.   if InitProc <> nil then TProcedure(InitProc);
  216. end;
  217.  
  218. procedure TWebApplication.OnExceptionHandler(Sender: TObject; E: Exception);
  219. begin
  220.   DoHandleException(E);
  221. end;
  222.  
  223. procedure TWebApplication.SetCacheConnections(Value: Boolean);
  224. var
  225.   I: Integer;
  226. begin
  227.   if Value <> FCacheConnections then
  228.   begin
  229.     FCacheConnections := Value;
  230.     if not Value then
  231.     begin
  232.       FCriticalSection.Enter;
  233.       try
  234.         for I := 0 to FInactiveWebModules.Count - 1 do
  235.           TDataModule(FInactiveWebModules[I]).Free;
  236.         FInactiveWebModules.Clear;  
  237.       finally
  238.         FCriticalSection.Leave;
  239.       end;
  240.     end;
  241.   end;
  242. end;
  243.  
  244. procedure TWebApplication.Run;
  245. begin
  246.   if not IsLibrary then AddExitProc(DoneVCLApplication);
  247.   Forms.Application.OnException := OnExceptionHandler;
  248. end;
  249.  
  250. end.
  251.