| (* | 
 |  * Licensed to the Apache Software Foundation (ASF) under one | 
 |  * or more contributor license agreements. See the NOTICE file | 
 |  * distributed with this work for additional information | 
 |  * regarding copyright ownership. The ASF licenses this file | 
 |  * to you under the Apache License, Version 2.0 (the | 
 |  * "License"); you may not use this file except in compliance | 
 |  * with the License. You may obtain a copy of the License at | 
 |  * | 
 |  *   http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, | 
 |  * software distributed under the License is distributed on an | 
 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 |  * KIND, either express or implied. See the License for the | 
 |  * specific language governing permissions and limitations | 
 |  * under the License. | 
 |  *) | 
 |  | 
 |  unit Thrift.Server; | 
 |  | 
 | interface | 
 |  | 
 | uses | 
 |   SysUtils, | 
 |   Thrift, | 
 |   Thrift.Protocol, | 
 |   Thrift.Transport; | 
 |  | 
 | type | 
 |   IServer = interface | 
 |     ['{CF9F56C6-BB39-4C7D-877B-43B416572CE6}'] | 
 |     procedure Serve; | 
 |     procedure Stop; | 
 |   end; | 
 |  | 
 |   TServerImpl = class abstract( TInterfacedObject, IServer ) | 
 |   public | 
 |     type | 
 |       TLogDelegate = reference to procedure( const str: string); | 
 |   protected | 
 |     FProcessor : IProcessor; | 
 |     FServerTransport : IServerTransport; | 
 |     FInputTransportFactory : ITransportFactory; | 
 |     FOutputTransportFactory : ITransportFactory; | 
 |     FInputProtocolFactory : IProtocolFactory; | 
 |     FOutputProtocolFactory : IProtocolFactory; | 
 |     FLogDelegate : TLogDelegate; | 
 |  | 
 |     class procedure DefaultLogDelegate( const str: string); | 
 |  | 
 |     procedure Serve; virtual; abstract; | 
 |     procedure Stop; virtual; abstract; | 
 |   public | 
 |     constructor Create( | 
 |       const AProcessor :IProcessor; | 
 |       const AServerTransport: IServerTransport; | 
 |       const AInputTransportFactory : ITransportFactory; | 
 |       const AOutputTransportFactory : ITransportFactory; | 
 |       const AInputProtocolFactory : IProtocolFactory; | 
 |       const AOutputProtocolFactory : IProtocolFactory; | 
 |       const ALogDelegate : TLogDelegate | 
 |       ); overload; | 
 |  | 
 |     constructor Create(  | 
 |       const AProcessor :IProcessor; | 
 |       const AServerTransport: IServerTransport | 
 | 	  ); overload; | 
 |  | 
 |     constructor Create( | 
 |       const AProcessor :IProcessor; | 
 |       const AServerTransport: IServerTransport; | 
 |       const ALogDelegate: TLogDelegate | 
 |       ); overload; | 
 |  | 
 |     constructor Create( | 
 |       const AProcessor :IProcessor; | 
 |       const AServerTransport: IServerTransport; | 
 |       const ATransportFactory : ITransportFactory | 
 |       ); overload; | 
 |  | 
 |     constructor Create( | 
 |       const AProcessor :IProcessor; | 
 |       const AServerTransport: IServerTransport; | 
 |       const ATransportFactory : ITransportFactory; | 
 |       const AProtocolFactory : IProtocolFactory | 
 |       ); overload; | 
 |   end; | 
 |  | 
 |   TSimpleServer = class( TServerImpl) | 
 |   private | 
 |     FStop : Boolean; | 
 |   public | 
 |     constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport); overload; | 
 |     constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport; | 
 |       ALogDel: TServerImpl.TLogDelegate); overload; | 
 |     constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport; | 
 |       const ATransportFactory: ITransportFactory); overload; | 
 |     constructor Create( const AProcessor: IProcessor; const AServerTransport: IServerTransport; | 
 |       const ATransportFactory: ITransportFactory; const AProtocolFactory: IProtocolFactory); overload; | 
 |  | 
 |     procedure Serve; override; | 
 |     procedure Stop; override; | 
 |   end; | 
 |  | 
 |  | 
 | implementation | 
 |  | 
 | { TServerImpl } | 
 |  | 
 | constructor TServerImpl.Create( const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport; const ALogDelegate: TLogDelegate); | 
 | var | 
 |   InputFactory, OutputFactory : IProtocolFactory; | 
 |   InputTransFactory, OutputTransFactory : ITransportFactory; | 
 |  | 
 | begin | 
 |   InputFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   OutputFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   InputTransFactory := TTransportFactoryImpl.Create; | 
 |   OutputTransFactory := TTransportFactoryImpl.Create; | 
 |  | 
 |   Create( | 
 |     AProcessor, | 
 |     AServerTransport, | 
 |     InputTransFactory, | 
 |     OutputTransFactory, | 
 |     InputFactory, | 
 |     OutputFactory, | 
 |     ALogDelegate | 
 |   ); | 
 | end; | 
 |  | 
 | constructor TServerImpl.Create(const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport); | 
 | var | 
 |   InputFactory, OutputFactory : IProtocolFactory; | 
 |   InputTransFactory, OutputTransFactory : ITransportFactory; | 
 |  | 
 | begin | 
 |   InputFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   OutputFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   InputTransFactory := TTransportFactoryImpl.Create; | 
 |   OutputTransFactory := TTransportFactoryImpl.Create; | 
 |  | 
 |   Create( | 
 |     AProcessor, | 
 |     AServerTransport, | 
 |     InputTransFactory, | 
 |     OutputTransFactory, | 
 |     InputFactory, | 
 |     OutputFactory, | 
 |     DefaultLogDelegate | 
 |   ); | 
 | end; | 
 |  | 
 | constructor TServerImpl.Create(const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory); | 
 | var | 
 |   InputProtocolFactory : IProtocolFactory; | 
 |   OutputProtocolFactory : IProtocolFactory; | 
 | begin | 
 |   InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |  | 
 |   Create( AProcessor, AServerTransport, ATransportFactory, ATransportFactory, | 
 |     InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate); | 
 | end; | 
 |  | 
 | constructor TServerImpl.Create(const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport; | 
 |   const AInputTransportFactory, AOutputTransportFactory: ITransportFactory; | 
 |   const AInputProtocolFactory, AOutputProtocolFactory: IProtocolFactory; | 
 |   const ALogDelegate : TLogDelegate); | 
 | begin | 
 |   FProcessor := AProcessor; | 
 |   FServerTransport := AServerTransport; | 
 |   FInputTransportFactory := AInputTransportFactory; | 
 |   FOutputTransportFactory := AOutputTransportFactory; | 
 |   FInputProtocolFactory := AInputProtocolFactory; | 
 |   FOutputProtocolFactory := AOutputProtocolFactory; | 
 |   FLogDelegate := ALogDelegate; | 
 | end; | 
 |  | 
 | class procedure TServerImpl.DefaultLogDelegate( const str: string); | 
 | begin | 
 |   Writeln( str ); | 
 | end; | 
 |  | 
 | constructor TServerImpl.Create( const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory; | 
 |   const AProtocolFactory: IProtocolFactory); | 
 | begin | 
 |   Create( AProcessor, AServerTransport, | 
 |           ATransportFactory, ATransportFactory, | 
 |           AProtocolFactory, AProtocolFactory, | 
 |           DefaultLogDelegate); | 
 | end; | 
 |  | 
 | { TSimpleServer } | 
 |  | 
 | constructor TSimpleServer.Create( const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport); | 
 | var | 
 |   InputProtocolFactory : IProtocolFactory; | 
 |   OutputProtocolFactory : IProtocolFactory; | 
 |   InputTransportFactory : ITransportFactory; | 
 |   OutputTransportFactory : ITransportFactory; | 
 | begin | 
 |   InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   InputTransportFactory := TTransportFactoryImpl.Create; | 
 |   OutputTransportFactory := TTransportFactoryImpl.Create; | 
 |  | 
 |   inherited Create( AProcessor, AServerTransport, InputTransportFactory, | 
 |     OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, DefaultLogDelegate); | 
 | end; | 
 |  | 
 | constructor TSimpleServer.Create( const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport; ALogDel: TServerImpl.TLogDelegate); | 
 | var | 
 |   InputProtocolFactory : IProtocolFactory; | 
 |   OutputProtocolFactory : IProtocolFactory; | 
 |   InputTransportFactory : ITransportFactory; | 
 |   OutputTransportFactory : ITransportFactory; | 
 | begin | 
 |   InputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   OutputProtocolFactory := TBinaryProtocolImpl.TFactory.Create; | 
 |   InputTransportFactory := TTransportFactoryImpl.Create; | 
 |   OutputTransportFactory := TTransportFactoryImpl.Create; | 
 |  | 
 |   inherited Create( AProcessor, AServerTransport, InputTransportFactory, | 
 |     OutputTransportFactory, InputProtocolFactory, OutputProtocolFactory, ALogDel); | 
 | end; | 
 |  | 
 | constructor TSimpleServer.Create( const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory); | 
 | begin | 
 |   inherited Create( AProcessor, AServerTransport, ATransportFactory, | 
 |     ATransportFactory, TBinaryProtocolImpl.TFactory.Create, TBinaryProtocolImpl.TFactory.Create, DefaultLogDelegate); | 
 | end; | 
 |  | 
 | constructor TSimpleServer.Create( const AProcessor: IProcessor; | 
 |   const AServerTransport: IServerTransport; const ATransportFactory: ITransportFactory; | 
 |   const AProtocolFactory: IProtocolFactory); | 
 | begin | 
 |   inherited Create( AProcessor, AServerTransport, ATransportFactory, | 
 |     ATransportFactory, AProtocolFactory, AProtocolFactory, DefaultLogDelegate); | 
 | end; | 
 |  | 
 | procedure TSimpleServer.Serve; | 
 | var | 
 |   client : ITransport; | 
 |   InputTransport : ITransport; | 
 |   OutputTransport : ITransport; | 
 |   InputProtocol : IProtocol; | 
 |   OutputProtocol : IProtocol; | 
 | begin | 
 |   try | 
 |     FServerTransport.Listen; | 
 |   except | 
 |     on E: Exception do | 
 |     begin | 
 |       FLogDelegate( E.ToString); | 
 |     end; | 
 |   end; | 
 |  | 
 |   client := nil; | 
 |   InputTransport := nil; | 
 |   OutputTransport := nil; | 
 |   InputProtocol := nil; | 
 |   OutputProtocol := nil; | 
 |  | 
 |   while (not FStop) do | 
 |   begin | 
 |     try | 
 |       client := FServerTransport.Accept; | 
 |       FLogDelegate( 'Client Connected!'); | 
 |       InputTransport := FInputTransportFactory.GetTransport( client ); | 
 |       OutputTransport := FOutputTransportFactory.GetTransport( client ); | 
 |       InputProtocol := FInputProtocolFactory.GetProtocol( InputTransport ); | 
 |       OutputProtocol := FOutputProtocolFactory.GetProtocol( OutputTransport ); | 
 |       while ( FProcessor.Process( InputProtocol, OutputProtocol )) do | 
 |       begin | 
 |         if FStop then Break; | 
 |       end; | 
 |     except | 
 |       on E: TTransportException do | 
 |       begin | 
 |         if FStop then | 
 |         begin | 
 |           FLogDelegate('TSimpleServer was shutting down, caught ' + E.ClassName); | 
 |         end; | 
 |       end; | 
 |       on E: Exception do | 
 |       begin | 
 |         FLogDelegate( E.ToString ); | 
 |       end; | 
 |     end; | 
 |     if InputTransport <> nil then | 
 |     begin | 
 |       InputTransport.Close; | 
 |     end; | 
 |     if OutputTransport <> nil then | 
 |     begin | 
 |       OutputTransport.Close; | 
 |     end; | 
 |   end; | 
 |  | 
 |   if FStop then | 
 |   begin | 
 |     try | 
 |       FServerTransport.Close; | 
 |     except | 
 |       on E: TTransportException do | 
 |       begin | 
 |         FLogDelegate('TServerTranport failed on close: ' + E.Message); | 
 |       end; | 
 |     end; | 
 |     FStop := False; | 
 |   end; | 
 | end; | 
 |  | 
 | procedure TSimpleServer.Stop; | 
 | begin | 
 |   FStop := True; | 
 |   FServerTransport.Close; | 
 | end; | 
 |  | 
 | end. |