From e9df17213cae2e3c1f06cbff9e5d6c8be021c66e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Van=20Canneyt?= Date: Fri, 22 Nov 2024 14:16:38 +0100 Subject: [PATCH] * OpenAPI support --- components/openapi/README.md | 9 + components/openapi/fraopenapisettings.lfm | 698 ++++++++++++++++++++++ components/openapi/fraopenapisettings.pas | 276 +++++++++ components/openapi/frmopenapiwizard.lfm | 78 +++ components/openapi/frmopenapiwizard.pas | 106 ++++ components/openapi/lazopenapi.lpk | 55 ++ components/openapi/lazopenapi.pas | 22 + components/openapi/reglazopenapi.pas | 126 ++++ components/openapi/ver_3_2_2/README.md | 4 + 9 files changed, 1374 insertions(+) create mode 100644 components/openapi/README.md create mode 100644 components/openapi/fraopenapisettings.lfm create mode 100644 components/openapi/fraopenapisettings.pas create mode 100644 components/openapi/frmopenapiwizard.lfm create mode 100644 components/openapi/frmopenapiwizard.pas create mode 100644 components/openapi/lazopenapi.lpk create mode 100644 components/openapi/lazopenapi.pas create mode 100644 components/openapi/reglazopenapi.pas create mode 100644 components/openapi/ver_3_2_2/README.md diff --git a/components/openapi/README.md b/components/openapi/README.md new file mode 100644 index 0000000000..6af8478aa0 --- /dev/null +++ b/components/openapi/README.md @@ -0,0 +1,9 @@ +Lazarus OpenAPI support. + +For help and instructions about this package, see +[https://wiki.freepascal.org/Lazarus-openapi](https://wiki.freepascal.org/Lazarus-openapi) + +When compiling with FPC 3.2.2, copy the fcl-jsonschema and fcl-openapi files +to directory ver_3_2_2. + +See also the instructions at [https://wiki.freepascal.org/Lazarus-openapi](https://wiki.freepascal.org/Lazarus-openapi) diff --git a/components/openapi/fraopenapisettings.lfm b/components/openapi/fraopenapisettings.lfm new file mode 100644 index 0000000000..43f1e14f19 --- /dev/null +++ b/components/openapi/fraopenapisettings.lfm @@ -0,0 +1,698 @@ +object GeneratorSettingsFrame: TGeneratorSettingsFrame + Left = 0 + Height = 500 + Top = 0 + Width = 711 + ClientHeight = 500 + ClientWidth = 711 + TabOrder = 0 + DesignLeft = 495 + DesignTop = 272 + object edtFile: TFileNameEdit + Left = 104 + Height = 28 + Top = 8 + Width = 591 + FileName = 'edtFile' + DialogOptions = [ofFileMustExist, ofEnableSizing, ofViewDetail] + Filter = 'JSON files|*.json|All files|*.*' + FilterIndex = 0 + HideDirectories = False + ButtonWidth = 23 + NumGlyphs = 1 + Anchors = [akTop, akLeft, akRight] + MaxLength = 0 + TabOrder = 0 + Text = 'edtFile' + end + object lblOpenAPIFile: TLabel + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = edtFile + AnchorSideRight.Control = edtFile + AnchorSideBottom.Control = edtFile + AnchorSideBottom.Side = asrBottom + Left = 16 + Height = 28 + Top = 8 + Width = 80 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight, akBottom] + AutoSize = False + BorderSpacing.Left = 16 + BorderSpacing.Right = 8 + Caption = 'OpenAPI file' + Layout = tlCenter + end + object cbGenServer: TCheckBox + AnchorSideLeft.Control = CBGenClient + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = CBGenClient + Left = 141 + Height = 23 + Top = 44 + Width = 121 + BorderSpacing.Left = 8 + Caption = 'Generate server' + TabOrder = 1 + end + object CBGenClient: TCheckBox + AnchorSideLeft.Control = lblOpenAPIFile + AnchorSideTop.Control = edtFile + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 23 + Top = 44 + Width = 117 + BorderSpacing.Top = 8 + Caption = 'Generate client' + TabOrder = 2 + end + object PCSettings: TPageControl + AnchorSideLeft.Control = Owner + AnchorSideTop.Control = CBGenClient + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 16 + Height = 409 + Top = 75 + Width = 679 + ActivePage = TSGeneral + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Left = 16 + BorderSpacing.Top = 8 + BorderSpacing.Right = 16 + BorderSpacing.Bottom = 16 + TabIndex = 0 + TabOrder = 3 + object TSGeneral: TTabSheet + Caption = 'General' + ClientHeight = 379 + ClientWidth = 669 + object CBDelphiCode: TCheckBox + AnchorSideLeft.Control = TSGeneral + AnchorSideTop.Control = TSGeneral + Left = 16 + Height = 23 + Top = 8 + Width = 98 + BorderSpacing.Left = 16 + BorderSpacing.Top = 8 + Caption = 'Delphi code' + TabOrder = 0 + end + object CBVerboseHeader: TCheckBox + AnchorSideLeft.Control = CBDelphiCode + AnchorSideTop.Control = CBDelphiCode + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 23 + Top = 39 + Width = 120 + BorderSpacing.Top = 8 + Caption = 'Verbose header' + TabOrder = 1 + end + object CBEnums: TCheckBox + AnchorSideLeft.Control = CBVerboseHeader + AnchorSideTop.Control = CBVerboseHeader + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 23 + Top = 70 + Width = 160 + BorderSpacing.Top = 8 + Caption = 'Use enumerated types' + TabOrder = 2 + end + object GBAutoNaming: TGroupBox + AnchorSideLeft.Control = CBEnums + AnchorSideTop.Control = CBEnums + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 147 + Top = 101 + Width = 560 + BorderSpacing.Top = 8 + Caption = 'Automatic file naming' + ClientHeight = 130 + ClientWidth = 558 + TabOrder = 3 + object edtUnitSuffix: TEdit + AnchorSideLeft.Control = lblUnitSuffix + AnchorSideTop.Control = lblUnitSuffix + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 32 + Width = 176 + BorderSpacing.Top = 8 + TabOrder = 0 + Text = 'edtUnitSuffix' + end + object lblUnitSuffix: TLabel + AnchorSideLeft.Control = GBAutoNaming + AnchorSideTop.Control = GBAutoNaming + Left = 16 + Height = 16 + Top = 8 + Width = 156 + BorderSpacing.Left = 16 + BorderSpacing.Top = 8 + Caption = 'Unit name suffix template' + end + object edtUnitExtension: TEdit + AnchorSideLeft.Control = lblUnitNameExtension + AnchorSideTop.Control = lblUnitNameExtension + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 92 + Width = 80 + BorderSpacing.Top = 8 + TabOrder = 1 + Text = 'edtUnitExtension' + end + object lblUnitNameExtension: TLabel + AnchorSideLeft.Control = edtUnitSuffix + AnchorSideTop.Control = edtUnitSuffix + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 68 + Width = 123 + BorderSpacing.Top = 8 + Caption = 'Unit name extension' + end + end + object edtServiceNameSuffix: TEdit + AnchorSideLeft.Control = lblServiceNameSuffix + AnchorSideTop.Control = lblServiceNameSuffix + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 280 + Width = 136 + BorderSpacing.Top = 8 + TabOrder = 4 + Text = 'edtServiceNameSuffix' + end + object edtServiceNamePrefix: TEdit + AnchorSideLeft.Control = Label1 + AnchorSideTop.Control = Label1 + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 340 + Width = 144 + BorderSpacing.Top = 8 + TabOrder = 5 + Text = 'edtServiceNamePrefix' + end + object lblServiceNameSuffix: TLabel + AnchorSideLeft.Control = GBAutoNaming + AnchorSideTop.Control = GBAutoNaming + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 256 + Width = 116 + BorderSpacing.Top = 8 + Caption = 'Service name suffix' + end + object Label1: TLabel + AnchorSideLeft.Control = edtServiceNameSuffix + AnchorSideTop.Control = edtServiceNameSuffix + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 316 + Width = 117 + BorderSpacing.Top = 8 + Caption = 'Service name prefix' + end + end + object TSData: TTabSheet + Caption = 'Data' + ClientHeight = 379 + ClientWidth = 669 + object edtDtoUnit: TEdit + AnchorSideLeft.Control = lblDtoUnitName + AnchorSideTop.Control = lblDtoUnitName + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 32 + Width = 160 + BorderSpacing.Top = 8 + TabOrder = 0 + Text = 'edtDtoUnit' + end + object edtSerializeUnit: TEdit + AnchorSideLeft.Control = lblDtoUnitName + AnchorSideTop.Control = lblSerializeUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 92 + Width = 160 + BorderSpacing.Top = 8 + TabOrder = 1 + Text = 'edtSerializeUnit' + end + object lblDtoUnitName: TLabel + AnchorSideLeft.Control = TSData + AnchorSideTop.Control = TSData + Left = 16 + Height = 16 + Top = 8 + Width = 86 + BorderSpacing.Left = 16 + BorderSpacing.Top = 8 + Caption = 'Dto unit name' + end + object lblSerializeUnit: TLabel + AnchorSideLeft.Control = lblDtoUnitName + AnchorSideTop.Control = edtDtoUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 68 + Width = 81 + BorderSpacing.Top = 8 + Caption = 'Serializer unit' + end + end + object TSClient: TTabSheet + Caption = 'Client' + ClientHeight = 379 + ClientWidth = 669 + object CBAsyncService: TCheckBox + AnchorSideLeft.Control = TSClient + AnchorSideTop.Control = TSClient + Left = 16 + Height = 23 + Top = 8 + Width = 172 + BorderSpacing.Left = 16 + BorderSpacing.Top = 8 + Caption = 'Asynchrone service calls' + TabOrder = 0 + OnChange = HandleSyncCheck + end + object cbCancelRequest: TCheckBox + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = CBAsyncService + AnchorSideTop.Side = asrBottom + Left = 40 + Height = 23 + Top = 39 + Width = 299 + BorderSpacing.Left = 24 + BorderSpacing.Top = 8 + Caption = 'Generate CancelRequest (asynchronous only)' + TabOrder = 1 + end + object edtClientServiceImplementationUnit: TEdit + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = lblClientServiceImplementationUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 154 + Width = 208 + BorderSpacing.Top = 8 + TabOrder = 2 + Text = 'edtClientServiceImplementationUnit' + end + object edtClientServiceInterfaceUnit: TEdit + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = lblClientServiceInterfaceUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 94 + Width = 208 + BorderSpacing.Top = 8 + TabOrder = 3 + Text = 'edtClientServiceInterfaceUnit' + end + object lblClientServiceInterfaceUnit: TLabel + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = cbCancelRequest + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 70 + Width = 198 + BorderSpacing.Top = 8 + Caption = 'Client service interface unit name' + end + object lblClientServiceImplementationUnit: TLabel + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = edtClientServiceInterfaceUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 130 + Width = 278 + BorderSpacing.Top = 8 + Caption = 'Client service proxy implementation unit name' + end + object edtClientServiceParentClass: TEdit + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = lblClientServiceParentClass + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 214 + Width = 208 + BorderSpacing.Top = 8 + TabOrder = 4 + Text = 'edtClientServiceParentClass' + end + object edtClientServiceParentUnit: TEdit + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = lblClientServiceParentUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 274 + Width = 208 + BorderSpacing.Top = 8 + TabOrder = 5 + Text = 'edtClientServiceParentUnit' + end + object lblClientServiceParentClass: TLabel + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = edtClientServiceImplementationUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 190 + Width = 154 + BorderSpacing.Top = 8 + Caption = 'Client service parent class' + end + object lblClientServiceParentUnit: TLabel + AnchorSideLeft.Control = CBAsyncService + AnchorSideTop.Control = edtClientServiceParentClass + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 250 + Width = 185 + BorderSpacing.Top = 8 + Caption = 'Client service parent unit name' + end + end + object TSServer: TTabSheet + Caption = 'Server' + ClientHeight = 379 + ClientWidth = 669 + object CBSkipImplementation: TCheckBox + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = CBAbstractCalls + AnchorSideTop.Side = asrBottom + Left = 40 + Height = 23 + Top = 39 + Width = 302 + BorderSpacing.Left = 24 + BorderSpacing.Top = 8 + Caption = 'Skip implementation unit (only when abstract)' + TabOrder = 0 + end + object CBAbstractCalls: TCheckBox + AnchorSideLeft.Control = TSServer + AnchorSideTop.Control = TSServer + Left = 16 + Height = 23 + Top = 8 + Width = 356 + BorderSpacing.Left = 16 + BorderSpacing.Top = 8 + Caption = 'Generate abstract service calls in HTTP handler module' + TabOrder = 1 + OnChange = HandleAbstract + end + object edtServerHandlerUnitName: TEdit + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = lblServerHandlerUnitName + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 94 + Width = 242 + BorderSpacing.Top = 8 + TabOrder = 2 + Text = 'edtServerHandlerUnitName' + end + object edtServerImplementationUnitName: TEdit + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = lblServerImplementationUnitName + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 154 + Width = 240 + BorderSpacing.Top = 8 + TabOrder = 3 + Text = 'edtServerImplementationUnitName' + end + object edtServerServiceParentClass: TEdit + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = lblServerServiceParentClass + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 214 + Width = 216 + BorderSpacing.Top = 8 + TabOrder = 4 + Text = 'edtServerServiceParentClass' + end + object edtServerServiceParentUnit: TEdit + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = lblServerServiceParentUnit + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 28 + Top = 275 + Width = 208 + BorderSpacing.Top = 8 + TabOrder = 5 + Text = 'edtServerServiceParentUnit' + end + object lblServerHandlerUnitName: TLabel + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = CBSkipImplementation + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 70 + Width = 151 + BorderSpacing.Top = 8 + Caption = 'Server handler unit name' + end + object lblServerImplementationUnitName: TLabel + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = edtServerHandlerUnitName + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 130 + Width = 199 + BorderSpacing.Top = 8 + Caption = 'Server implementation unit name' + end + object lblServerServiceParentClass: TLabel + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = edtServerImplementationUnitName + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 190 + Width = 157 + BorderSpacing.Top = 8 + Caption = 'Server service parent class' + end + object lblServerServiceParentUnit: TLabel + AnchorSideLeft.Control = CBAbstractCalls + AnchorSideTop.Control = edtServerServiceParentClass + AnchorSideTop.Side = asrBottom + Left = 16 + Height = 16 + Top = 251 + Width = 187 + BorderSpacing.Top = 9 + Caption = 'server service parent unit name' + end + end + object TSUUIDMap: TTabSheet + Caption = 'GUID map' + ClientHeight = 379 + ClientWidth = 669 + object VLEUUIDMap: TValueListEditor + Left = 8 + Height = 316 + Top = 16 + Width = 653 + Anchors = [akTop, akLeft, akRight, akBottom] + DefaultColWidth = 200 + FixedCols = 0 + RowCount = 2 + TabOrder = 0 + DisplayOptions = [doColumnTitles, doAutoColResize] + KeyOptions = [keyEdit, keyAdd, keyDelete, keyUnique] + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goEditing, goAutoAddRows, goAlwaysShowEditor, goThumbTracking] + TitleCaptions.Strings = ( + 'Interface' + 'GUID' + ) + ColWidths = ( + 325 + 324 + ) + end + object edtUUIDMap: TFileNameEdit + Left = 112 + Height = 28 + Top = 343 + Width = 461 + DialogKind = dkSave + DialogOptions = [ofPathMustExist, ofEnableSizing, ofViewDetail] + FilterIndex = 0 + HideDirectories = False + ButtonWidth = 23 + NumGlyphs = 1 + Anchors = [akLeft, akRight, akBottom] + BorderSpacing.Right = 8 + MaxLength = 0 + TabOrder = 1 + end + object lblUUIDMap: TLabel + AnchorSideTop.Control = edtUUIDMap + AnchorSideRight.Control = edtUUIDMap + AnchorSideBottom.Control = edtUUIDMap + AnchorSideBottom.Side = asrBottom + Left = 8 + Height = 28 + Top = 343 + Width = 96 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Right = 8 + Caption = 'GUID Map file' + Layout = tlCenter + end + object btnLoadUUIDMap: TButton + Left = 586 + Height = 25 + Top = 343 + Width = 75 + Anchors = [akRight, akBottom] + Caption = 'Load' + TabOrder = 2 + OnClick = btnLoadUUIDMapClick + end + end + object TSServiceMap: TTabSheet + Caption = 'Service name map' + ClientHeight = 379 + ClientWidth = 669 + object VLEServiceMap: TValueListEditor + Left = 8 + Height = 316 + Top = 16 + Width = 653 + Anchors = [akTop, akLeft, akRight, akBottom] + DefaultColWidth = 200 + FixedCols = 0 + RowCount = 2 + TabOrder = 0 + DisplayOptions = [doColumnTitles, doAutoColResize] + KeyOptions = [keyEdit, keyAdd, keyDelete, keyUnique] + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing, goEditing, goAutoAddRows, goAlwaysShowEditor, goThumbTracking] + TitleCaptions.Strings = ( + 'Interface' + 'GUID' + ) + ColWidths = ( + 325 + 324 + ) + end + object lblUUIDMap1: TLabel + AnchorSideTop.Control = edtServiceMapFile + AnchorSideRight.Control = edtServiceMapFile + AnchorSideBottom.Control = edtServiceMapFile + AnchorSideBottom.Side = asrBottom + Left = 8 + Height = 28 + Top = 343 + Width = 96 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Right = 8 + Caption = 'Service Map file' + Layout = tlCenter + end + object edtServiceMapFile: TFileNameEdit + Left = 112 + Height = 28 + Top = 343 + Width = 461 + DialogKind = dkSave + DialogOptions = [ofPathMustExist, ofEnableSizing, ofViewDetail] + FilterIndex = 0 + HideDirectories = False + ButtonWidth = 23 + NumGlyphs = 1 + Anchors = [akLeft, akRight, akBottom] + BorderSpacing.Right = 8 + MaxLength = 0 + TabOrder = 1 + end + object btnLoadUUIDMap1: TButton + Left = 586 + Height = 25 + Top = 343 + Width = 75 + Anchors = [akRight, akBottom] + Caption = 'Load' + TabOrder = 2 + OnClick = btnLoadUUIDMap1Click + end + end + end + object cbOpenFiles: TCheckBox + AnchorSideLeft.Control = cbGenServer + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = CBGenClient + Left = 270 + Height = 23 + Top = 44 + Width = 192 + BorderSpacing.Left = 8 + Caption = 'Open generated files in IDE' + TabOrder = 4 + end + object cbAddToProject: TCheckBox + AnchorSideLeft.Control = cbOpenFiles + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = CBGenClient + AnchorSideBottom.Control = CBGenClient + AnchorSideBottom.Side = asrBottom + Left = 470 + Height = 23 + Top = 44 + Width = 114 + Anchors = [akTop, akLeft, akBottom] + BorderSpacing.Left = 8 + Caption = 'Add To Project' + TabOrder = 5 + end +end diff --git a/components/openapi/fraopenapisettings.pas b/components/openapi/fraopenapisettings.pas new file mode 100644 index 0000000000..3cd0998d90 --- /dev/null +++ b/components/openapi/fraopenapisettings.pas @@ -0,0 +1,276 @@ +unit fraopenapisettings; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, EditBtn, StdCtrls, ComCtrls, ValEdit, fpopenapi.codegen; + +type + + { TGeneratorSettingsFrame } + + TGeneratorSettingsFrame = class(TFrame) + btnLoadUUIDMap: TButton; + btnLoadUUIDMap1: TButton; + cbGenServer: TCheckBox; + CBGenClient: TCheckBox; + CBDelphiCode: TCheckBox; + cbOpenFiles: TCheckBox; + CBVerboseHeader: TCheckBox; + CBEnums: TCheckBox; + CBAsyncService: TCheckBox; + cbCancelRequest: TCheckBox; + CBSkipImplementation: TCheckBox; + CBAbstractCalls: TCheckBox; + cbAddToProject: TCheckBox; + edtClientServiceImplementationUnit: TEdit; + edtClientServiceInterfaceUnit: TEdit; + edtClientServiceParentClass: TEdit; + edtClientServiceParentUnit: TEdit; + edtServerHandlerUnitName: TEdit; + edtServerImplementationUnitName: TEdit; + edtServerServiceParentClass: TEdit; + edtServerServiceParentUnit: TEdit; + edtServiceNameSuffix: TEdit; + edtServiceNamePrefix: TEdit; + edtSerializeUnit: TEdit; + edtDtoUnit: TEdit; + edtUnitExtension: TEdit; + edtUnitSuffix: TEdit; + edtUUIDMap: TFileNameEdit; + edtServiceMapFile: TFileNameEdit; + GBAutoNaming: TGroupBox; + Label1: TLabel; + lblUUIDMap: TLabel; + lblServerServiceParentUnit: TLabel; + lblServerServiceParentClass: TLabel; + lblServerImplementationUnitName: TLabel; + lblServerHandlerUnitName: TLabel; + lblClientServiceInterfaceUnit: TLabel; + lblClientServiceImplementationUnit: TLabel; + lblClientServiceParentClass: TLabel; + lblClientServiceParentUnit: TLabel; + lblDtoUnitName: TLabel; + lblSerializeUnit: TLabel; + lblServiceNameSuffix: TLabel; + lblUnitNameExtension: TLabel; + lblOpenAPIFile : TLabel; + edtFile : TFileNameEdit; + lblUnitSuffix: TLabel; + lblUUIDMap1: TLabel; + PCSettings: TPageControl; + TSServiceMap: TTabSheet; + TSUUIDMap: TTabSheet; + TSData: TTabSheet; + TSGeneral: TTabSheet; + TSClient: TTabSheet; + TSServer: TTabSheet; + VLEUUIDMap: TValueListEditor; + VLEServiceMap: TValueListEditor; + procedure btnLoadUUIDMap1Click(Sender: TObject); + procedure btnLoadUUIDMapClick(Sender: TObject); + procedure HandleAbstract(Sender: TObject); + procedure HandleSyncCheck(Sender: TObject); + private + FGenerator: TOpenAPICodeGen; + procedure CheckAbstract; + procedure CheckAsync; + function GetAddToProject: Boolean; + function GetOpenAPIFileName: String; + function GetOpenGeneratedFiles: Boolean; + procedure LoadFileToEditor(aEditor: TValueListEditor; const aFilename, aDescription: String); + procedure SetAddToProject(AValue: Boolean); + procedure SetOpenAPIFileName(AValue: String); + procedure SetOpenGeneratedFiles(AValue: Boolean); + public + procedure InitFileNameEdits(Const aBaseDir : string); + Procedure SaveSettings; + procedure ShowSettings; + function Modified : Boolean; + Property OpenAPIFileName : String Read GetOpenAPIFileName Write SetOpenAPIFileName; + Property OpenGeneratedFiles : Boolean Read GetOpenGeneratedFiles Write SetOpenGeneratedFiles; + Property AddFilesToProject : Boolean Read GetAddToProject Write SetAddToProject; + Property Generator : TOpenAPICodeGen Read FGenerator Write FGenerator; + end; + + +implementation + +{$R *.lfm} + +{ TGeneratorSettingsFrame } + + +procedure TGeneratorSettingsFrame.ShowSettings; + +begin + With Generator do + begin + cbGenServer.Checked:=GenerateServer; + cbGenClient.Checked:=GenerateClient; + CBAbstractCalls.Checked:=AbstractServiceCalls; + CBSkipImplementation.Checked:=SkipServerServiceImplementationModule; + CBAsyncService.Checked:=AsyncService; + CheckAsync; + CBDelphiCode.checked:=DelphiCode; + CBVerboseHeader.Checked:=VerboseHeader; + cbCancelRequest.Checked:=not ParentHasCancelRequest; + CBEnums.Checked:=UseEnums; + edtClientServiceImplementationUnit.Text:=ClientServiceImplementationUnit; + edtClientServiceInterfaceUnit.Text:=ClientServiceInterfaceUnit; + edtClientServiceParentClass.Text:=ClientServiceParentClass; + edtClientServiceParentUnit.Text:=ClientServiceParentUnit; + edtServerHandlerUnitName.Text:=ServerServiceInterfaceUnit; + edtServerImplementationUnitName.Text:=ServerServiceImplementationUnit; + edtServerServiceParentClass.Text:=ServerServiceParentClass; + edtServerServiceParentUnit.Text:=ServerServiceParentUnit; + edtServiceNameSuffix.Text:=ServiceNameSuffix; + edtServiceNamePrefix.Text:=ServiceNamePrefix; + edtSerializeUnit.Text:=SerializeUnit; + edtDtoUnit.Text:=DtoUnit; + edtUnitExtension.Text:=UnitExtension; + edtUnitSuffix.Text:=UnitSuffix; + end; +end; + +function TGeneratorSettingsFrame.Modified: Boolean; + +begin + Result:=False; + With Generator do + begin + Result:=Result or (CBAbstractCalls.Checked<>AbstractServiceCalls); + Result:=Result or (CBSkipImplementation.Checked<>SkipServerServiceImplementationModule); + Result:=Result or (CBAsyncService.Checked<>AsyncService); + Result:=Result or (CBDelphiCode.checked<>DelphiCode); + Result:=Result or (CBVerboseHeader.Checked<>VerboseHeader); + Result:=Result or (cbCancelRequest.Checked<>not ParentHasCancelRequest); + Result:=Result or (CBEnums.Checked<>UseEnums); + Result:=Result or (edtClientServiceImplementationUnit.Text<>ClientServiceImplementationUnit); + Result:=Result or (edtClientServiceInterfaceUnit.Text<>ClientServiceInterfaceUnit); + Result:=Result or (edtClientServiceParentClass.Text<>ClientServiceParentClass); + Result:=Result or (edtClientServiceParentUnit.Text<>ClientServiceParentUnit); + Result:=Result or (edtServerHandlerUnitName.Text<>ServerServiceInterfaceUnit); + Result:=Result or (edtServerImplementationUnitName.Text<>ServerServiceImplementationUnit); + Result:=Result or (edtServerServiceParentClass.Text<>ServerServiceParentClass); + Result:=Result or (edtServerServiceParentUnit.Text<>ServerServiceParentUnit); + Result:=Result or (edtServiceNameSuffix.Text<>ServiceNameSuffix); + Result:=Result or (edtServiceNamePrefix.Text<>ServiceNamePrefix); + Result:=Result or (edtSerializeUnit.Text<>SerializeUnit); + Result:=Result or (edtDtoUnit.Text<>DtoUnit); + Result:=Result or (edtUnitExtension.Text<>UnitExtension); + Result:=Result or (edtUnitSuffix.Text<>UnitSuffix); + end; +end; + +procedure TGeneratorSettingsFrame.CheckAsync; + +begin + cbCancelRequest.Enabled:=CBAsyncService.Checked; +end; + +function TGeneratorSettingsFrame.GetAddToProject: Boolean; +begin + Result:=cbAddToProject.Checked; +end; + +function TGeneratorSettingsFrame.GetOpenAPIFileName: String; +begin + Result:=edtFile.FileName; +end; + +function TGeneratorSettingsFrame.GetOpenGeneratedFiles: Boolean; +begin + result:=cbOpenFiles.Checked; +end; + +procedure TGeneratorSettingsFrame.CheckAbstract; + +begin + CBSkipImplementation.Enabled:=CBAbstractCalls.Checked; +end; + +procedure TGeneratorSettingsFrame.HandleSyncCheck(Sender: TObject); +begin + CheckAsync +end; + +procedure TGeneratorSettingsFrame.HandleAbstract(Sender: TObject); +begin + CheckAbstract; +end; + +procedure TGeneratorSettingsFrame.LoadFileToEditor(aEditor : TValueListEditor; const aFilename,aDescription : String); + +begin + if not FileExists(aFileName) then + Raise EInOutError.CreateFmt('Cannot load %s: file %s does not exist.',[aDescription,aFileName]); + aEditor.Strings.LoadFromFile(aFileName); +end; + +procedure TGeneratorSettingsFrame.SetAddToProject(AValue: Boolean); +begin + cbAddToProject.Checked:=aValue; +end; + +procedure TGeneratorSettingsFrame.SetOpenAPIFileName(AValue: String); +begin + edtFile.FileName:=aValue; +end; + +procedure TGeneratorSettingsFrame.SetOpenGeneratedFiles(AValue: Boolean); +begin + cbOpenFiles.Checked:=aValue; +end; + +procedure TGeneratorSettingsFrame.InitFileNameEdits(const aBaseDir: string); +begin + edtFile.InitialDir:=aBaseDir; + edtUUIDMap.InitialDir:=aBaseDir; + edtServiceMapFile.InitialDir:=aBaseDir; +end; + +procedure TGeneratorSettingsFrame.btnLoadUUIDMapClick(Sender: TObject); +begin + LoadFileToEditor(VLEUUIDMap,edtUUIDMap.FileName,'GUID map'); +end; + +procedure TGeneratorSettingsFrame.btnLoadUUIDMap1Click(Sender: TObject); +begin + LoadFileToEditor(VLEServiceMap,edtServiceMapFile.FileName,'service map'); +end; + +procedure TGeneratorSettingsFrame.SaveSettings; +begin + With Generator do + begin + GenerateServer:=cbGenServer.Checked; + GenerateClient:=cbGenClient.Checked; + AbstractServiceCalls:=CBAbstractCalls.Checked; + SkipServerServiceImplementationModule:=CBSkipImplementation.Checked; + AsyncService:=CBAsyncService.Checked; + DelphiCode:=CBDelphiCode.checked; + VerboseHeader:=CBVerboseHeader.Checked; + ParentHasCancelRequest:=not cbCancelRequest.Checked; + UseEnums:=CBEnums.Checked; + ClientServiceImplementationUnit:=edtClientServiceImplementationUnit.Text; + ClientServiceInterfaceUnit:=edtClientServiceInterfaceUnit.Text; + ClientServiceParentClass:=edtClientServiceParentClass.Text; + ClientServiceParentUnit:=edtClientServiceParentUnit.Text; + ServerServiceInterfaceUnit:=edtServerHandlerUnitName.Text; + ServerServiceImplementationUnit:=edtServerImplementationUnitName.Text; + ServerServiceParentClass:=edtServerServiceParentClass.Text; + ServerServiceParentUnit:=edtServerServiceParentUnit.Text; + ServiceNameSuffix:=edtServiceNameSuffix.Text; + ServiceNamePrefix:=edtServiceNamePrefix.Text; + SerializeUnit:=edtSerializeUnit.Text; + DtoUnit:=edtDtoUnit.Text; + UnitExtension:=edtUnitExtension.Text; + UnitSuffix:=edtUnitSuffix.Text; + end; +end; + +end. + diff --git a/components/openapi/frmopenapiwizard.lfm b/components/openapi/frmopenapiwizard.lfm new file mode 100644 index 0000000000..96898b8a60 --- /dev/null +++ b/components/openapi/frmopenapiwizard.lfm @@ -0,0 +1,78 @@ +object OpenapiWizardForm: TOpenapiWizardForm + Left = 579 + Height = 594 + Top = 250 + Width = 719 + Caption = 'OpenAPI to code' + ClientHeight = 594 + ClientWidth = 719 + LCLVersion = '4.99.0.0' + OnClose = FormClose + OnCreate = FormCreate + inline fraSettings: TGeneratorSettingsFrame + Height = 510 + Width = 719 + Align = alClient + ClientHeight = 510 + ClientWidth = 719 + end + object bpOpenAPICodegen: TButtonPanel + Left = 6 + Height = 38 + Top = 550 + Width = 707 + OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True + HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True + CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True + CancelButton.Name = 'CancelButton' + CancelButton.DefaultCaption = True + TabOrder = 1 + ShowButtons = [pbOK, pbCancel] + end + object pnlBottom: TPanel + Left = 0 + Height = 34 + Top = 510 + Width = 719 + Align = alBottom + BevelOuter = bvNone + ClientHeight = 34 + ClientWidth = 719 + TabOrder = 2 + object edtBaseFileName: TFileNameEdit + Left = 192 + Height = 28 + Top = 4 + Width = 511 + FileName = 'edtbaseOutput' + DialogKind = dkSave + DialogOptions = [ofPathMustExist, ofEnableSizing, ofViewDetail] + FilterIndex = 0 + HideDirectories = False + ButtonWidth = 23 + NumGlyphs = 1 + Anchors = [akTop, akLeft, akRight] + MaxLength = 0 + TabOrder = 0 + Text = 'edtbaseOutput' + end + object lblBaseOutput: TLabel + AnchorSideTop.Control = edtBaseFileName + AnchorSideRight.Control = edtBaseFileName + AnchorSideBottom.Control = edtBaseFileName + AnchorSideBottom.Side = asrBottom + Left = 16 + Height = 28 + Top = 4 + Width = 168 + Alignment = taRightJustify + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Right = 8 + Caption = 'Base for output filenames' + Layout = tlCenter + end + end +end diff --git a/components/openapi/frmopenapiwizard.pas b/components/openapi/frmopenapiwizard.pas new file mode 100644 index 0000000000..f4b395f0cb --- /dev/null +++ b/components/openapi/frmopenapiwizard.pas @@ -0,0 +1,106 @@ +unit frmopenapiwizard; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ButtonPanel, ExtCtrls, EditBtn, StdCtrls, fraopenapisettings, fpopenapi.codegen; + +type + + { TOpenapiWizardForm } + + TOpenapiWizardForm = class(TForm) + bpOpenAPICodegen: TButtonPanel; + edtBaseFileName: TFileNameEdit; + fraSettings: TGeneratorSettingsFrame; + lblBaseOutput: TLabel; + pnlBottom: TPanel; + procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); + procedure FormCreate(Sender: TObject); + private + FGenerator: TOpenAPICodeGen; + function GetAddToProject: Boolean; + function GetBaseFileName: String; + function GetOpenAPIFileName: String; + function GetOPenGeneratedFiles: Boolean; + procedure SetBaseFileName(AValue: String); + procedure SetGenerator(AValue: TOpenAPICodeGen); + procedure SetOpenAPIFileName(AValue: String); + public + procedure InitFileNameEdits(const aBaseDir: String); + Property Generator : TOpenAPICodeGen read FGenerator Write SetGenerator; + Property BaseFileName : String Read GetBaseFileName Write SetBaseFileName; + Property OpenAPIFileName : String Read GetOpenAPIFileName Write SetOpenAPIFileName; + Property OpenGeneratedFiles : Boolean Read GetOPenGeneratedFiles; + Property AddToProject : Boolean Read GetAddToProject; + end; + +var + OpenapiWizardForm: TOpenapiWizardForm; + +implementation + +{$R *.lfm} + +{ TOpenapiWizardForm } + +procedure TOpenapiWizardForm.FormCreate(Sender: TObject); +begin + OpenAPIFileName:=''; + BaseFileName:=''; +end; + +procedure TOpenapiWizardForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); +begin + if ModalResult=mrOK then + FraSettings.SaveSettings; +end; + +function TOpenapiWizardForm.GetBaseFileName: String; +begin + Result:=edtBaseFileName.FileName; +end; + +function TOpenapiWizardForm.GetAddToProject: Boolean; +begin + Result:=fraSettings.AddFilesToProject; +end; + +function TOpenapiWizardForm.GetOpenAPIFileName: String; +begin + Result:=fraSettings.OpenAPIFileName; +end; + +function TOpenapiWizardForm.GetOPenGeneratedFiles: Boolean; +begin + Result:=fraSettings.OpenGeneratedFiles; +end; + +procedure TOpenapiWizardForm.SetBaseFileName(AValue: String); +begin + edtBaseFileName.FileName:=aValue; +end; + +procedure TOpenapiWizardForm.SetGenerator(AValue: TOpenAPICodeGen); +begin + if FGenerator=AValue then Exit; + FGenerator:=AValue; + fraSettings.Generator:=AValue; + fraSettings.ShowSettings; +end; + +procedure TOpenapiWizardForm.SetOpenAPIFileName(AValue: String); +begin + fraSettings.OpenAPIFileName:=aValue; +end; + +procedure TOpenapiWizardForm.InitFileNameEdits(const aBaseDir: String); +begin + fraSettings.InitFileNameEdits(aBaseDir); + edtBaseFileName.InitialDir:=aBaseDir; +end; + +end. + diff --git a/components/openapi/lazopenapi.lpk b/components/openapi/lazopenapi.lpk new file mode 100644 index 0000000000..70795ed085 --- /dev/null +++ b/components/openapi/lazopenapi.lpk @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/openapi/lazopenapi.pas b/components/openapi/lazopenapi.pas new file mode 100644 index 0000000000..1ef34a5063 --- /dev/null +++ b/components/openapi/lazopenapi.pas @@ -0,0 +1,22 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit lazopenapi; + +{$warn 5023 off : no warning about unused units} +interface + +uses + fraopenapisettings, frmopenapiwizard, reglazopenapi, LazarusPackageIntf; + +implementation + +procedure Register; +begin + RegisterUnit('reglazopenapi', @reglazopenapi.Register); +end; + +initialization + RegisterPackage('lazopenapi', @Register); +end. diff --git a/components/openapi/reglazopenapi.pas b/components/openapi/reglazopenapi.pas new file mode 100644 index 0000000000..63496e5aad --- /dev/null +++ b/components/openapi/reglazopenapi.pas @@ -0,0 +1,126 @@ +unit reglazopenapi; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LazIDEIntf, IDECommands; + +procedure register; + +implementation + +uses MenuIntf, frmopenapiwizard, forms, controls, fpopenapi.reader, fpopenapi.objects, fpopenapi.codegen; + +Resourcestring + SCMDOpenAPIWizard = 'ShowOpenAPICodeGenerator'; + SCMDOpenAPIWizardCaption = 'OpenAPI code generator...'; + +Type + + { TLazOpenAPICodeGen } + + TLazOpenAPICodeGen = class(TOpenAPICodeGen) + Function ResolveFullFileName(aKind : TUnitKind) : String; + end; + +Procedure GenerateFiles(const aOpenAPIFile, aBaseOutputFile : string; aGenerator : TLazOpenAPICodeGen); + +var + Loader : TOpenAPIReader; + API : TOpenAPI; + +begin + Loader:=Nil; + API:=TOpenAPI.Create; + try + Loader:=TOpenAPIReader.Create(Nil); + Loader.ReadFromFile(API,aOpenAPIFile); + aGenerator.API:=API; + aGenerator.BaseOutputFileName:=aBaseOutputFile; + aGenerator.Execute; + finally + Loader.Free; + API.Free; + end; +end; + +procedure ShowOpenAPIWizard(Sender: TObject); + +var + opts : TOpenFlags; + +var + frm : TOpenapiWizardForm; + lGenerator : TLazOpenAPICodeGen; + +begin + opts:=[ofOnlyIfExists, ofRevert, ofAddToRecent, ofRegularFile]; + + frm:=Nil; + lGenerator:=TLazOpenAPICodeGen.Create(Application); + try + frm:=TOpenapiWizardForm.Create(Application); + frm.InitFileNameEdits(ExtractFilePath(lazarusIDE.ActiveProject.ProjectInfoFile)); + frm.Generator:=lGenerator; + if frm.ShowModal=mrOK then + begin + if frm.AddToProject then + Include(opts,ofAddToProject); + GenerateFiles(frm.OpenAPIFileName,frm.BaseFileName,lGenerator); + if frm.OpenGeneratedFiles then + begin + LazarusIDE.DoOpenEditorFile(lGenerator.ResolveFullFileName(ukDto),-1,-1,opts); + LazarusIDE.DoOpenEditorFile(lGenerator.ResolveFullFileName(ukSerialize),-1,-1,opts); + if lGenerator.GenerateClient then + begin + LazarusIDE.DoOpenEditorFile(lGenerator.ResolveFullFileName(ukClientServiceIntf),-1,-1,opts); + LazarusIDE.DoOpenEditorFile(lGenerator.ResolveFullFileName(ukClientServiceImpl),-1,-1,opts); + end; + if lGenerator.GenerateServer then + begin + LazarusIDE.DoOpenEditorFile(lGenerator.ResolveFullFileName(ukServerServiceHandler),-1,-1,opts); + LazarusIDE.DoOpenEditorFile(lGenerator.ResolveFullFileName(ukServerServiceImpl),-1,-1,opts); + end; + end; + end; + finally + lGenerator.Free; + frm.Free; + end; +end; + + + +procedure register; + +var + CmdToolsMenu : TIDECommandCategory; + OpenAPIWizardCommand : TIDECommand; + +begin + // search shortcut category + CmdToolsMenu:=IDECommandList.FindCategoryByName(CommandCategoryToolMenuName); + // register shortcut + OpenAPIWizardCommand:=RegisterIDECommand(CmdToolsMenu, + SCMDOpenAPIWizard, + SCMDOpenAPIWizardCaption, + CleanIDEShortCut, + CleanIDEShortCut, nil, @ShowOpenAPIWizard); + // register menu item in View menu + RegisterIDEMenuCommand(itmCustomTools, + SCMDOpenAPIWizard, + SCMDOpenAPIWizardCaption, nil, nil, OpenAPIWizardCommand); + +end; + +{ TLazOpenAPICodeGen } + +function TLazOpenAPICodeGen.ResolveFullFileName(aKind: TUnitKind): String; +begin + Result:=ResolveUnit(aKind,True); +end; + +end. + diff --git a/components/openapi/ver_3_2_2/README.md b/components/openapi/ver_3_2_2/README.md new file mode 100644 index 0000000000..ba85b9f766 --- /dev/null +++ b/components/openapi/ver_3_2_2/README.md @@ -0,0 +1,4 @@ +When compiling with FPC 3.2.2, copy the fcl-jsonschema and fcl-openapi files +here. + +See also the instructions at [https://wiki.freepascal.org/Lazarus-openapi](https://wiki.freepascal.org/Lazarus-openapi)