home *** CD-ROM | disk | FTP | other *** search
/ Delphi Anthology / aDELPHI.iso / Runimage / Delphi50 / Source / Vcl / objbrkr.pas < prev    next >
Pascal/Delphi Source File  |  1999-08-11  |  8KB  |  301 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Visual Component Library         }
  5. {                                                       }
  6. {       Copyright (c) 1997,99 Inprise Corporation       }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit ObjBrkr;
  11.  
  12. {$T-}
  13.  
  14. interface
  15.  
  16. uses
  17.   MConnect, Classes, SysUtils;
  18.  
  19. type
  20.  
  21.   EBrokerException = class(Exception);
  22.  
  23. { TServerItem }
  24.  
  25.   TServerItem = class(TCollectionItem)
  26.   private
  27.     FEnabled: Boolean;
  28.     FComputerName: string;
  29.     FHasFailed: Boolean;
  30.     FPort: Integer;
  31.   protected
  32.     function GetDisplayName: string; override;
  33.   public
  34.     constructor Create(AOwner: TCollection); override;
  35.     property HasFailed: Boolean read FHasFailed write FHasFailed;
  36.   published
  37.     property ComputerName: string read FComputerName write FComputerName;
  38.     property Port: Integer read FPort write FPort default 211;
  39.     property Enabled: Boolean read FEnabled write FEnabled default True;
  40.   end;
  41.  
  42. { TServerCollection }
  43.  
  44.   TServerCollection = class(TOwnedCollection)
  45.   private
  46.     function GetItem(Index: Integer): TServerItem;
  47.     procedure SetItem(Index: Integer; Value: TServerItem);
  48.   public
  49.     constructor Create(AOwner: TComponent);
  50.     function GetBalancedName: string;
  51.     function GetNextName: string;
  52.     function FindServer(const ComputerName: string): TServerItem;
  53.     property Items[Index: Integer]: TServerItem read GetItem write SetItem; default;
  54.   end;
  55.  
  56. { TSimpleObjectBroker }
  57.  
  58.   TSimpleObjectBroker = class(TCustomObjectBroker)
  59.   private
  60.     FServers: TServerCollection;
  61.     FLoadBalanced: Boolean;
  62.     procedure SetServers(Value: TServerCollection);
  63.     function IsServersStored: Boolean;
  64.     function GetNextComputer: string;
  65.     function GetServerData: OleVariant;
  66.     procedure SetServerData(const Value: OleVariant);
  67.   public
  68.     constructor Create(AOwner: TComponent); override;
  69.     destructor Destroy; override;
  70.     procedure SaveToStream(Stream: TStream);
  71.     procedure LoadFromStream(Stream: TStream);
  72.     property ServerData: OleVariant read GetServerData write SetServerData;
  73.     { From TCustomObjectBroker }
  74.     procedure SetConnectStatus(ComputerName: string; Success: Boolean); override;
  75.     function GetComputerForGUID(GUID: TGUID): string; override;
  76.     function GetComputerForProgID(const ProgID): string; override;
  77.     function GetPortForComputer(const ComputerName: string): Integer; override;
  78.   published
  79.     property Servers: TServerCollection read FServers write SetServers stored IsServersStored;
  80.     property LoadBalanced: Boolean read FLoadBalanced write FLoadBalanced default False;
  81.   end;
  82.  
  83. implementation
  84.  
  85. uses MidConst;
  86.  
  87. { TServerItem }
  88.  
  89. constructor TServerItem.Create(AOwner: TCollection);
  90. begin
  91.   inherited Create(AOwner);
  92.   FPort := 211;
  93.   FHasFailed := False;
  94.   FEnabled := True;
  95. end;
  96.  
  97. function TServerItem.GetDisplayName: string;
  98. begin
  99.   Result := ComputerName;
  100.   if Result = '' then
  101.     Result := inherited GetDisplayName;
  102. end;
  103.  
  104. { TServerCollection }
  105.  
  106. constructor TServerCollection.Create(AOwner: TComponent);
  107. begin
  108.   inherited Create(AOwner, TServerItem);
  109. end;
  110.  
  111. function TServerCollection.FindServer(const ComputerName: string): TServerItem;
  112. var
  113.   i: Integer;
  114. begin
  115.   Result := nil;
  116.   for i := 0 to Count - 1 do
  117.     if Items[i].ComputerName = ComputerName then
  118.     begin
  119.       Result := Items[i];
  120.       break;
  121.     end;
  122. end;
  123.  
  124. function TServerCollection.GetItem(Index: Integer): TServerItem;
  125. begin
  126.   Result := TServerItem(inherited GetItem(Index));
  127. end;
  128.  
  129. function TServerCollection.GetNextName: string;
  130. var
  131.   i :Integer;
  132. begin
  133.   Result := '';
  134.   for i := 0 to Count - 1 do
  135.     if (not Items[i].HasFailed) and (Items[i].Enabled) then
  136.     begin
  137.       Result := Items[i].ComputerName;
  138.       break;
  139.     end;
  140.   if Result = '' then
  141.     raise EBrokerException.CreateRes(@SNoServers);
  142. end;
  143.  
  144. function TServerCollection.GetBalancedName: string;
  145. var
  146.   i, GoodCount: Integer;
  147.   GoodServers: array of TServerItem;
  148. begin
  149.   GoodCount := 0;
  150.   SetLength(GoodServers, Count);
  151.   for i := 0 to Count - 1 do
  152.     if (not Items[i].HasFailed) and (Items[i].Enabled) then
  153.     begin
  154.       GoodServers[GoodCount] := Items[i];
  155.       Inc(GoodCount);
  156.     end;
  157.   if GoodCount = 0 then
  158.     raise EBrokerException.CreateRes(@SNoServers);
  159.   Randomize;
  160.   Result := GoodServers[Random(GoodCount)].ComputerName;
  161. end;
  162.  
  163. procedure TServerCollection.SetItem(Index: Integer; Value: TServerItem);
  164. begin
  165.   inherited SetItem(Index, Value);
  166. end;
  167.  
  168. { TSimpleObjectBroker }
  169.  
  170. constructor TSimpleObjectBroker.Create(AOwner: TComponent);
  171. begin
  172.   inherited Create(AOwner);
  173.   FLoadBalanced := False;
  174.   FServers := TServerCollection.Create(Self);
  175. end;
  176.  
  177. destructor TSimpleObjectBroker.Destroy;
  178. begin
  179.   FServers.Free;
  180.   inherited Destroy;
  181. end;
  182.  
  183. function TSimpleObjectBroker.GetServerData: OleVariant;
  184. var
  185.   Stream: TMemoryStream;
  186.   P: Pointer;
  187. begin
  188.   Stream := TMemoryStream.Create;
  189.   try
  190.     SaveToStream(Stream);
  191.     Result := VarArrayCreate([0, Stream.Size], varByte);
  192.     P := VarArrayLock(Result);
  193.     try
  194.       Move(Stream.Memory^, P^, Stream.Size);
  195.     finally
  196.       VarArrayUnlock(Result);
  197.     end;
  198.   finally
  199.     Stream.Free;
  200.   end;
  201. end;
  202.  
  203. procedure TSimpleObjectBroker.SetServerData(const Value: OleVariant);
  204. var
  205.   Stream: TMemoryStream;
  206.   P: Pointer;
  207. begin
  208.   if VarIsNull(Value) or VarIsEmpty(Value) then
  209.     Servers.Clear else
  210.   begin
  211.     Stream := TMemoryStream.Create;
  212.     try
  213.       Stream.Size := VarArrayHighBound(Value, 1);
  214.       P := VarArrayLock(Value);
  215.       try
  216.         Stream.Write(P^, Stream.Size);
  217.       finally
  218.         VarArrayUnlock(Value);
  219.       end;
  220.       Stream.Position := 0;
  221.       LoadFromStream(Stream);
  222.     finally
  223.       Stream.Free;
  224.     end;
  225.   end;
  226. end;
  227.  
  228. procedure TSimpleObjectBroker.SaveToStream(Stream: TStream);
  229. var
  230.   Writer: TWriter;
  231. begin
  232.   Writer := TWriter.Create(Stream, 1024);
  233.   try
  234.     Writer.WriteCollection(Servers);
  235.   finally
  236.     Writer.Free;
  237.   end;
  238. end;
  239.  
  240. procedure TSimpleObjectBroker.LoadFromStream(Stream: TStream);
  241. var
  242.   Reader: TReader;
  243. begin
  244.   Servers.Clear;
  245.   Reader := TReader.Create(Stream, 1024);
  246.   try
  247.     Reader.ReadValue;
  248.     Reader.ReadCollection(Servers);
  249.   finally
  250.     Reader.Free;
  251.   end;
  252. end;
  253.  
  254. function TSimpleObjectBroker.GetNextComputer: string;
  255. begin
  256.   if LoadBalanced then
  257.     Result := Servers.GetBalancedName else
  258.     Result := Servers.GetNextName;
  259. end;
  260.  
  261. function TSimpleObjectBroker.GetComputerForGUID(GUID: TGUID): string;
  262. begin
  263.   Result := GetNextComputer;
  264. end;
  265.  
  266. function TSimpleObjectBroker.GetComputerForProgID(const ProgID): string;
  267. begin
  268.   Result := GetNextComputer;
  269. end;
  270.  
  271. function TSimpleObjectBroker.GetPortForComputer(const ComputerName: string): Integer;
  272. var
  273.   Server: TServerItem;
  274. begin
  275.   Server := Servers.FindServer(ComputerName);
  276.   if Assigned(Server) then
  277.     Result := Server.Port else
  278.     Result := 0;
  279. end;
  280.  
  281. function TSimpleObjectBroker.IsServersStored: Boolean;
  282. begin
  283.   Result := Servers.Count > 0;
  284. end;
  285.  
  286. procedure TSimpleObjectBroker.SetConnectStatus(ComputerName: string;
  287.   Success: Boolean);
  288. var
  289.   Server: TServerItem;
  290. begin
  291.   Server := Servers.FindServer(ComputerName);
  292.   if Assigned(Server) then Server.HasFailed := not Success;
  293. end;
  294.  
  295. procedure TSimpleObjectBroker.SetServers(Value: TServerCollection);
  296. begin
  297.   FServers.Assign(Value);
  298. end;
  299.  
  300. end.
  301.