Browse Source

* Some improvements to proxy server module generation

Michaël Van Canneyt 7 months ago
parent
commit
ce72fbe54d

+ 31 - 1
packages/fcl-openapi/src/fpopenapi.codegen.pp

@@ -79,6 +79,7 @@ type
     FOnLog: TSchemaCodeGenLogEvent;
     FOnLog: TSchemaCodeGenLogEvent;
     FParentHasCancelRequest: Boolean;
     FParentHasCancelRequest: Boolean;
     FServerParentClass: String;
     FServerParentClass: String;
+    FServerProxyFormFile: Boolean;
     FServerProxyModuleName: String;
     FServerProxyModuleName: String;
     FServerProxyModuleParentName: String;
     FServerProxyModuleParentName: String;
     FServerProxyModuleParentUnit: String;
     FServerProxyModuleParentUnit: String;
@@ -96,6 +97,7 @@ type
     FUnitNames : Array [TUnitKind] of string;
     FUnitNames : Array [TUnitKind] of string;
     procedure CleanMaps;
     procedure CleanMaps;
     function GetBaseOutputUnitName: string;
     function GetBaseOutputUnitName: string;
+    function GetServerProxyModuleName: String;
     function GetServerProxyModuleParentUnit: String;
     function GetServerProxyModuleParentUnit: String;
     function GetUnitName(AIndex: TUnitKind): String;
     function GetUnitName(AIndex: TUnitKind): String;
     function GetUnitSuffix(aKind: TUnitKind): String;
     function GetUnitSuffix(aKind: TUnitKind): String;
@@ -193,13 +195,15 @@ type
     // Server proxy unit name serservice parent class name
     // Server proxy unit name serservice parent class name
     Property ServerProxyUnit : String index ukServerProxy Read GetUnitName Write SetUnitName;
     Property ServerProxyUnit : String index ukServerProxy Read GetUnitName Write SetUnitName;
     // Class name for server proxy datamodule.
     // Class name for server proxy datamodule.
-    Property ServerProxyModuleName : String Read FServerProxyModuleName Write FServerProxyModuleName;
+    Property ServerProxyModuleName : String Read GetServerProxyModuleName Write FServerProxyModuleName;
     // Class name for server proxy parent class.
     // Class name for server proxy parent class.
     Property ServerProxyModuleParentName : String Read FServerProxyModuleParentName Write FServerProxyModuleParentName;
     Property ServerProxyModuleParentName : String Read FServerProxyModuleParentName Write FServerProxyModuleParentName;
     // Unit name where server proxy parent class is defined.
     // Unit name where server proxy parent class is defined.
     Property ServerProxyModuleParentUnit : String Read GetServerProxyModuleParentUnit Write FServerProxyModuleParentUnit;
     Property ServerProxyModuleParentUnit : String Read GetServerProxyModuleParentUnit Write FServerProxyModuleParentUnit;
     // Define service properties using their interface definition.
     // Define service properties using their interface definition.
     Property ServerProxyUseServiceInterface : Boolean Read FServerProxyUseServiceInterface Write FServerProxyUseServiceInterface;
     Property ServerProxyUseServiceInterface : Boolean Read FServerProxyUseServiceInterface Write FServerProxyUseServiceInterface;
+    // Generate form file for ServerProxy module
+    Property ServerProxyFormFile : Boolean Read FServerProxyFormFile Write FServerProxyFormFile;
     // Prefix for client/server service name
     // Prefix for client/server service name
     Property ServiceNameSuffix : String Read FServiceNameSuffix Write FServiceNameSuffix;
     Property ServiceNameSuffix : String Read FServiceNameSuffix Write FServiceNameSuffix;
     // Prefix for client/server service name
     // Prefix for client/server service name
@@ -237,6 +241,8 @@ Const
   KeyServerProxyModuleParentName = 'ServerProxyModuleParentName';
   KeyServerProxyModuleParentName = 'ServerProxyModuleParentName';
   KeyServerProxyModuleParentUnit = 'ServerProxyModuleParentUnit';
   KeyServerProxyModuleParentUnit = 'ServerProxyModuleParentUnit';
   KeyServerProxyUseServiceInterface = 'ServerProxyModuleUseInterface';
   KeyServerProxyUseServiceInterface = 'ServerProxyModuleUseInterface';
+  KeyServerProxyFormFile            = 'ServerProxyFormFile';
+  KeyServerProxyUnit                = 'ServerProxyUnit' ;
 
 
 { TOpenAPICodeGen }
 { TOpenAPICodeGen }
 
 
@@ -315,11 +321,14 @@ begin
     AbstractServiceCalls:=ReadBool(lSection,KeyAbstractServiceCalls,AbstractServiceCalls);
     AbstractServiceCalls:=ReadBool(lSection,KeyAbstractServiceCalls,AbstractServiceCalls);
     ServiceNameSuffix:=ReadString(lSection,KeyServiceNameSuffix,ServiceNameSuffix);
     ServiceNameSuffix:=ReadString(lSection,KeyServiceNameSuffix,ServiceNameSuffix);
     ServiceNamePrefix:=ReadString(lSection,KeyServiceNamePrefix,ServiceNamePrefix);
     ServiceNamePrefix:=ReadString(lSection,KeyServiceNamePrefix,ServiceNamePrefix);
+
     GenerateServerProxyModule:=ReadBool(lSection,KeyGenerateServerProxyModule,GenerateServerProxyModule);
     GenerateServerProxyModule:=ReadBool(lSection,KeyGenerateServerProxyModule,GenerateServerProxyModule);
     ServerProxyModuleName:=ReadString(lSection,KeyServerProxyModuleName,ServerProxyModuleName);
     ServerProxyModuleName:=ReadString(lSection,KeyServerProxyModuleName,ServerProxyModuleName);
     ServerProxyModuleParentName:=ReadString(lSection,KeyServerProxyModuleParentName,ServerProxyModuleParentName);
     ServerProxyModuleParentName:=ReadString(lSection,KeyServerProxyModuleParentName,ServerProxyModuleParentName);
     ServerProxyModuleParentUnit:=ReadString(lSection,KeyServerProxyModuleParentName,ServerProxyModuleParentUnit);
     ServerProxyModuleParentUnit:=ReadString(lSection,KeyServerProxyModuleParentName,ServerProxyModuleParentUnit);
     ServerProxyUseServiceInterface:=ReadBool(lSection,KeyServerProxyUseServiceInterface,ServerProxyUseServiceInterface);
     ServerProxyUseServiceInterface:=ReadBool(lSection,KeyServerProxyUseServiceInterface,ServerProxyUseServiceInterface);
+    ServerProxyUnit:=ReadString(lSection,KeyServerProxyUnit,ServerProxyUnit);
+    ServerProxyFormFile:=ReadBool(lSection,KeyServerProxyFormFile,ServerProxyFormFile);
     end;
     end;
 end;
 end;
 
 
@@ -364,7 +373,16 @@ begin
     WriteBool(lSection,KeyAbstractServiceCalls,AbstractServiceCalls);
     WriteBool(lSection,KeyAbstractServiceCalls,AbstractServiceCalls);
     WriteString(lSection,KeyServiceNameSuffix,ServiceNameSuffix);
     WriteString(lSection,KeyServiceNameSuffix,ServiceNameSuffix);
     WriteString(lSection,KeyServiceNamePrefix,ServiceNamePrefix);
     WriteString(lSection,KeyServiceNamePrefix,ServiceNamePrefix);
+    WriteString(lSection,KeyServiceNameSuffix,ServiceNameSuffix);
+
+    WriteString(lSection,KeyServerProxyModuleName,ServerProxyModuleName);
+    WriteString(lSection,KeyServerProxyModuleParentUnit,ServerProxyModuleParentUnit);
+    WriteString(lSection,KeyServerProxyUnit,ServerProxyUnit);
+    WriteBool(lSection,KeyServerProxyUseServiceInterface,ServerProxyUseServiceInterface);
+    WriteBool(lSection,KeyServerProxyFormFile,ServerProxyFormFile);
+    WriteBool(lSection,KeyGenerateServerProxyModule, GenerateServerProxyModule);
     end;
     end;
+
 end;
 end;
 
 
 procedure TOpenAPICodeGen.SaveConfig(aConfigFile: String);
 procedure TOpenAPICodeGen.SaveConfig(aConfigFile: String);
@@ -422,6 +440,13 @@ begin
   Result := ExtractFileName(BaseOutputFileName);
   Result := ExtractFileName(BaseOutputFileName);
 end;
 end;
 
 
+function TOpenAPICodeGen.GetServerProxyModuleName: String;
+begin
+  Result:=FServerProxyModuleName;
+  if Result='' then
+    Result:='TServerProxy';
+end;
+
 function TOpenAPICodeGen.GetServerProxyModuleParentUnit: String;
 function TOpenAPICodeGen.GetServerProxyModuleParentUnit: String;
 begin
 begin
   Result:=FServerProxyModuleParentUnit;
   Result:=FServerProxyModuleParentUnit;
@@ -435,6 +460,8 @@ end;
 function TOpenAPICodeGen.GetUnitName(AIndex: TUnitKind): String;
 function TOpenAPICodeGen.GetUnitName(AIndex: TUnitKind): String;
 begin
 begin
   Result:=FUnitNames[aIndex];
   Result:=FUnitNames[aIndex];
+  if Result='' then
+
 end;
 end;
 
 
 procedure TOpenAPICodeGen.SetUnitName(AIndex: TUnitKind; AValue: String);
 procedure TOpenAPICodeGen.SetUnitName(AIndex: TUnitKind; AValue: String);
@@ -748,8 +775,11 @@ begin
     codegen.UseInterfaceType:=ServerProxyUseServiceInterface;
     codegen.UseInterfaceType:=ServerProxyUseServiceInterface;
     codegen.ServiceImplementationUnit := ResolveUnit(ukClientServiceImpl);
     codegen.ServiceImplementationUnit := ResolveUnit(ukClientServiceImpl);
     codegen.ServiceInterfaceUnit := ResolveUnit(ukClientServiceIntf);
     codegen.ServiceInterfaceUnit := ResolveUnit(ukClientServiceIntf);
+    codegen.FormFile:=FServerProxyFormFile;
     codegen.Execute(aData);
     codegen.Execute(aData);
     codegen.Source.SaveToFile(lFileName);
     codegen.Source.SaveToFile(lFileName);
+    if codegen.FormFile then
+      codegen.Form.SaveToFile(ChangeFileExt(lFileName,'.lfm'));
   finally
   finally
     codegen.Free;
     codegen.Free;
   end;
   end;

+ 134 - 16
packages/fcl-openapi/src/fpopenapi.generators.pp

@@ -32,6 +32,11 @@ uses
   fpopenapi.types,
   fpopenapi.types,
   fpopenapi.pascaltypes;
   fpopenapi.pascaltypes;
 
 
+Const
+  DefaultServerProxyName = 'TServerProxy';
+  DefaultServerProxyParent = 'TDataModule';
+  DefaultServerProxyParentUnit = 'Classes';
+
 type
 type
 
 
   { TJSONSchemaCodeGeneratorHelper }
   { TJSONSchemaCodeGeneratorHelper }
@@ -198,24 +203,38 @@ type
 
 
   { TServerProxyServiceModule }
   { TServerProxyServiceModule }
 
 
+  { TServerProxyServiceModuleCodeGen }
+
   TServerProxyServiceModuleCodeGen = class(TOpenApiPascalCodeGen)
   TServerProxyServiceModuleCodeGen = class(TOpenApiPascalCodeGen)
   private
   private
+    FFormFile: Boolean;
     FProxyClassName: string;
     FProxyClassName: string;
     FProxyParentClass: string;
     FProxyParentClass: string;
     FProxyParentUnit: string;
     FProxyParentUnit: string;
+    FProxyVarName: String;
     FServiceImplementationUnit: string;
     FServiceImplementationUnit: string;
     FServiceInterfaceUnit: string;
     FServiceInterfaceUnit: string;
     FUseInterfaceType: Boolean;
     FUseInterfaceType: Boolean;
+    FForm : TStrings;
+    procedure CheckDefaults;
+    function GetProxyVarName: String;
+    procedure SetProxyClassName(const aValue: string);
+  Protected
   public
   public
     constructor Create(AOwner: TComponent); override;
     constructor Create(AOwner: TComponent); override;
+    Destructor Destroy; override;
     procedure GenerateModule;
     procedure GenerateModule;
+    procedure GenerateFormFile;
     procedure Execute(aData: TAPIData); virtual;
     procedure Execute(aData: TAPIData); virtual;
     property ServiceInterfaceUnit: string read FServiceInterfaceUnit write FServiceInterfaceUnit;
     property ServiceInterfaceUnit: string read FServiceInterfaceUnit write FServiceInterfaceUnit;
     property ServiceImplementationUnit: string read FServiceImplementationUnit write FServiceImplementationUnit;
     property ServiceImplementationUnit: string read FServiceImplementationUnit write FServiceImplementationUnit;
     property ProxyParentClass: string read FProxyParentClass write FProxyParentClass;
     property ProxyParentClass: string read FProxyParentClass write FProxyParentClass;
     property ProxyParentUnit: string read FProxyParentUnit write FProxyParentUnit;
     property ProxyParentUnit: string read FProxyParentUnit write FProxyParentUnit;
     Property UseInterfaceType : Boolean Read FUseInterfaceType Write FUseInterfaceType;
     Property UseInterfaceType : Boolean Read FUseInterfaceType Write FUseInterfaceType;
-    Property ProxyClassName : string Read FProxyClassName Write FProxyClassName;
+    Property ProxyClassName : string Read FProxyClassName Write SetProxyClassName;
+    Property ProxyVarName : String Read GetProxyVarName Write FProxyVarName;
+    Property FormFile : Boolean Read FFormFile Write FFormFile;
+    Property Form : TStrings Read FForm Write FForm;
   end;
   end;
 
 
 
 
@@ -1338,39 +1357,65 @@ end;
 
 
 { TServerServiceModule }
 { TServerServiceModule }
 
 
+function TServerProxyServiceModuleCodeGen.GetProxyVarName: String;
+begin
+  Result:=FProxyVarName;
+  if Result='' then
+    Result:=Copy(ProxyClassName,2,Length(ProxyClassName)-1);
+end;
+
+procedure TServerProxyServiceModuleCodeGen.SetProxyClassName(const aValue: string);
+begin
+  if FProxyClassName=aValue then Exit;
+  FProxyClassName:=aValue;
+  CheckDefaults;
+end;
+
 constructor TServerProxyServiceModuleCodeGen.Create(AOwner: TComponent);
 constructor TServerProxyServiceModuleCodeGen.Create(AOwner: TComponent);
 begin
 begin
   inherited Create(AOwner);
   inherited Create(AOwner);
-  FProxyClassName:='TServerProxy';
-  FProxyParentClass:='TDataModule';
-  FProxyParentUnit:='Classes';
+  FForm:=TStringList.Create;
+  CheckDefaults;
+end;
+
+destructor TServerProxyServiceModuleCodeGen.Destroy;
+begin
+  FreeAndNil(FForm);
+  inherited Destroy;
+end;
+
+procedure TServerProxyServiceModuleCodeGen.CheckDefaults;
+begin
+  if FProxyClassName='' then
+    FProxyClassName:=DefaultServerProxyName;
+  if FProxyParentClass='' then
+    FProxyParentClass:=DefaultServerProxyParent;
+  if FProxyParentUnit='' then
+    FProxyParentUnit:=DefaultServerProxyParentUnit;
 end;
 end;
 
 
 procedure TServerProxyServiceModuleCodeGen.GenerateModule;
 procedure TServerProxyServiceModuleCodeGen.GenerateModule;
 
 
 var
 var
   I: integer;
   I: integer;
-  lUnits : String;
+  lClass,lUnits : String;
   lService: TAPIService;
   lService: TAPIService;
 
 
 begin
 begin
   GenerateFPCDirectives();
   GenerateFPCDirectives();
-
+  CheckDefaults;
   Addln('unit %s;', [Self.OutputUnitName]);
   Addln('unit %s;', [Self.OutputUnitName]);
   Addln('');
   Addln('');
   Addln('interface');
   Addln('interface');
   Addln('');
   Addln('');
   Addln('uses');
   Addln('uses');
   indent;
   indent;
-  If Not UseInterfaceType then
-    lUnits:=ServiceImplementationUnit
-  else
-    lUnits:=ServiceInterfaceUnit;
+  lUnits:=ServiceInterfaceUnit+', '+ServiceImplementationUnit;
   if not (SameText(ProxyParentUnit,'Classes') or SameText(ProxyParentUnit,'System.Classes')) then
   if not (SameText(ProxyParentUnit,'Classes') or SameText(ProxyParentUnit,'System.Classes')) then
     if DelphiCode then
     if DelphiCode then
       lUnits:='System.Classes, '+lUnits
       lUnits:='System.Classes, '+lUnits
     else
     else
-      lUnits:='Classes, '+lUnits;
+      lUnits:='Classes, fpWebClient, '+lUnits;
   AddLn('%s, %s;', [ProxyParentUnit, lUnits]);
   AddLn('%s, %s;', [ProxyParentUnit, lUnits]);
   undent;
   undent;
   Addln('');
   Addln('');
@@ -1379,11 +1424,22 @@ begin
   Addln('%s = class(%s)',[ProxyClassName,ProxyParentClass]);
   Addln('%s = class(%s)',[ProxyClassName,ProxyParentClass]);
   Addln('private');
   Addln('private');
   indent;
   indent;
+  Addln('FWebClient : TAbstractWebClient;');
+  Addln('FBaseURL : TAbstractWebClient;');
   for I:=0 to APIData.ServiceCount-1 do
   for I:=0 to APIData.ServiceCount-1 do
     begin
     begin
     lService:=APIData.Services[I];
     lService:=APIData.Services[I];
-    Addln('F%s : %s;',[lService.ServiceName,lService.ServiceInterfaceName]);
+    lClass:=lService.ServiceProxyImplementationClassName;
+    Addln('F%s : %s;',[lService.ServiceName,lClass]);
     end;
     end;
+  if UseInterfaceType then
+    for I:=0 to APIData.ServiceCount-1 do
+      begin
+      lService:=APIData.Services[I];
+      lClass:=lService.ServiceProxyImplementationClassName;
+      Addln('function Get%s : %s;',[lService.ServiceName,lService.ServiceInterfaceName]);
+      end;
+  Addln('Procedure SetBaseURL(const aValue : string);');
   undent;
   undent;
   Addln('protected');
   Addln('protected');
   indent;
   indent;
@@ -1395,29 +1451,42 @@ begin
   for I:=0 to APIData.ServiceCount-1 do
   for I:=0 to APIData.ServiceCount-1 do
     begin
     begin
     lService:=APIData.Services[I];
     lService:=APIData.Services[I];
-    Addln('Property %s : %s read F%s;',[lService.ServiceName,lService.ServiceInterfaceName,lService.ServiceName]);
+    if UseInterfaceType then
+      Addln('Property %s : %s read Get%s;',[lService.ServiceName,lService.ServiceInterfaceName,lService.ServiceName])
+    else
+      Addln('Property %s : %s read F%s;',[lService.ServiceName,lService.ServiceProxyImplementationClassName,lService.ServiceName]);
     end;
     end;
+  Addln('Property BaseURL : String Read FBaseURL Write SetBaseURL;',[lService.ServiceName,lService.ServiceInterfaceName,lService.ServiceName]);
   undent;
   undent;
   Addln('end;');
   Addln('end;');
   undent;
   undent;
   Addln('');
   Addln('');
+  if FormFile then
+    begin
+    Addln('var %s : %s;',[ProxyVarName,ProxyClassName]);
+    Addln('');
+    end;
   Addln('implementation');
   Addln('implementation');
   Addln('');
   Addln('');
   Addln('uses');
   Addln('uses');
   indent;
   indent;
-  if UseInterfaceType then
-    Addln('%s,', [ServiceImplementationUnit]);
   if DelphiCode then
   if DelphiCode then
     Addln('System.SysUtils;')
     Addln('System.SysUtils;')
   else
   else
     Addln('SysUtils;');
     Addln('SysUtils;');
   undent;
   undent;
+  if FormFile then
+    begin
+    Addln('');
+    Addln('{$R *.lfm}');
+    end;
   Addln('');
   Addln('');
   Addln('constructor %s.Create(aOwner : TComponent);',[ProxyClassName]);
   Addln('constructor %s.Create(aOwner : TComponent);',[ProxyClassName]);
   Addln('');
   Addln('');
   Addln('begin');
   Addln('begin');
   indent;
   indent;
   Addln('Inherited;');
   Addln('Inherited;');
+  Addln('FWebClient:=DefaultWebClientClass.Create(Self);');
   Addln('CreateServices;');
   Addln('CreateServices;');
   undent;
   undent;
   Addln('end;');
   Addln('end;');
@@ -1430,18 +1499,67 @@ begin
   for I:=0 to APIData.ServiceCount-1 do
   for I:=0 to APIData.ServiceCount-1 do
     begin
     begin
     lService:=APIData.Services[I];
     lService:=APIData.Services[I];
-    Addln('F%s:=%s.create(Self);',[lService.ServiceName,lService.ServiceProxyImplementationClassName]);
+    lClass:=lService.ServiceProxyImplementationClassName;
+    Addln('F%s:=%s.create(Self);',[lService.ServiceName,lClass]);
+    Addln('%s(F%s).WebClient:=FWebClient',[lClass,lService.ServiceName]);
     end;
     end;
   undent;
   undent;
   Addln('end;');
   Addln('end;');
   Addln('');
   Addln('');
+  Addln('');
+  Addln('Procedure %s.SetBaseURL(const aValue : string);',[ProxyClassName]);
+  Addln('');
+  Addln('begin');
+  Indent;
+  Addln('FBaseURL:=aValue;');
+  for I:=0 to APIData.ServiceCount-1 do
+    begin
+    lService:=APIData.Services[I];
+    Addln('F%s.BaseURL:=aValue;',[lService.ServiceName]);
+    end;
+  undent;
+  Addln('end;');
+  Addln('');
+  Addln('');
+  for I:=0 to APIData.ServiceCount-1 do
+    begin
+    lService:=APIData.Services[I];
+    lClass:=lService.ServiceProxyImplementationClassName;
+    Addln('function %s.Get%s : %s;',[ProxyClassName,lService.ServiceName,lService.ServiceInterfaceName]);
+    Addln('');
+    Addln('begin');
+    Indent;
+    Addln('Result:=F%s;',[lService.ServiceName]);
+    Undent;
+    Addln('end;');
+    Addln('');
+    Addln('');
+    end;
+  Addln('');
   Addln('end.');
   Addln('end.');
 end;
 end;
 
 
+procedure TServerProxyServiceModuleCodeGen.GenerateFormFile;
+
+begin
+  With FForm Do
+    begin
+    Add('object %s: %s',[ProxyVarName,ProxyClassName]);
+    Add('  OldCreateOrder = False');
+    Add('  Height = 150');
+    Add('  HorizontalOffset = 547');
+    Add('  VerticalOffset = 323');
+    Add('  Width = 150');
+    Add('end');
+    end;
+end;
+
 procedure TServerProxyServiceModuleCodeGen.Execute(aData: TAPIData);
 procedure TServerProxyServiceModuleCodeGen.Execute(aData: TAPIData);
 begin
 begin
   SetTypeData(aData);
   SetTypeData(aData);
   GenerateModule;
   GenerateModule;
+  if FFormFile then
+    GenerateFormFile;
 end;
 end;