unit uRODLToPascalAsync; {----------------------------------------------------------------------------} { RemObjects SDK Library - CodeGen } { } { compiler: Delphi 5 and up, Kylix 2 and up } { platform: Win32, Linux } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the RemObjects SDK } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$IFDEF LINUX} {$I ../RemObjects.inc} {$ELSE} {$I ..\RemObjects.inc} {$ENDIF LINUX} interface uses uRODL; type { TRODLToPascalAsync } TRODLToPascalAsync = class(TRODLConverter) private procedure WriteServiceDeclarationInterface(aService: TRODLService); procedure WriteServiceDeclarationProxy(aService: TRODLService); procedure WriteServiceDeclarationCoClass(aService: TRODLService); procedure WriteCoClass(aLibrary : TRODLLibrary; aService: TRODLService); // function IsSOAPService(aService : TRODLService) : boolean; protected procedure IntConvert(const aLibrary : TRODLLibrary; const aTargetEntity : string = ''); override; public class function GetTargetFileName(const aLibrary : TRODLLibrary; const aTargetEntity : string = ''): string; override; end; implementation uses SysUtils, Classes, Dialogs, uROTypes, {$IFDEF DELPHI5} ComObj, {$ENDIF} uRODLGenTools, uRODLToPascal, uRODLToPascalIntf, uROClasses; { TRODLToPascalAsync } procedure TRODLToPascalAsync.IntConvert(const aLibrary: TRODLLibrary; const aTargetEntity: string); var {x,} i : integer; s : string; lServices: IROStrings; begin try Write(Format('unit %s;', [ChangeFileExt(GetTargetFileName(aLibrary), '')])); WriteEmptyLine; WriteLines(IntfInvkNotice); WriteEmptyLine; write('{$I Remobjects.inc}'); WriteEmptyLine; Write('interface'); WriteEmptyLine; Write('uses'); Write('{vcl:} Classes, TypInfo,',PASCAL_INDENTATION_LEVEL_1); Write('{RemObjects:} uROXMLIntf, uROClasses, uROTypes, uROClientIntf, uROAsync,',PASCAL_INDENTATION_LEVEL_1); if aLibrary.UseCount > 0 then begin s := ''; for i := 0 to aLibrary.UseCount-1 do begin if s <> '' then s := s+', '; if aLibrary.Use[i].LoadedRodlLibraryName <> '' then s := s+aLibrary.Use[i].LoadedRodlLibraryName+'_Intf, ' +aLibrary.Use[i].LoadedRodlLibraryName+'_Async' else s := s+ChangeFileExt(ExtractFilename(aLibrary.Use[i].RodlFile),'')+'_Intf, ' +ChangeFileExt(ExtractFilename(aLibrary.Use[i].RodlFile),'')+'_Async'; end; { for } s := s+','; Write('{Used RODLs:} '+s,PASCAL_INDENTATION_LEVEL_1); end; Write('{Project:} '+ChangeFileExt(TRODLToIntf.GetTargetFileName(aLibrary),'')+';',PASCAL_INDENTATION_LEVEL_1); lServices := aLibrary.CalcServiceOrder; WriteEmptyLine; if aLibrary.ServiceCount > 0 then begin Write('type'); (* for i := 0 to (aLibrary.ServiceCount-1) do begin if not aLibrary.Services[i].IsFromUsedRodl then Write(Format('I%s_Async = interface;', [aLibrary.Services[i].Name]), PASCAL_INDENTATION_LEVEL_1); end; for i := 0 to (aLibrary.ServiceCount-1) do begin if not aLibrary.Services[i].IsFromUsedRodl then Write(Format('Co%s_Async = class;', [aLibrary.Services[i].Name]), PASCAL_INDENTATION_LEVEL_1); end; for i := 0 to (aLibrary.ServiceCount-1) do begin if not aLibrary.Services[i].IsFromUsedRodl then Write(Format('T%s_AsyncProxy = class;', [aLibrary.Services[i].Name]),PASCAL_INDENTATION_LEVEL_1); end; *) for i := 0 to lServices.Count -1 do begin if not TRODLService(lServices.Objects[i]).IsFromUsedRodl then WriteServiceDeclarationInterface(TRODLService(lServices.Objects[i])); end; for i := 0 to lServices.Count -1 do begin if not TRODLService(lServices.Objects[i]).IsFromUsedRodl then WriteServiceDeclarationCoClass(TRODLService(lServices.Objects[i])); end; for i := 0 to lServices.Count -1 do begin if not TRODLService(lServices.Objects[i]).IsFromUsedRodl then WriteServiceDeclarationProxy(TRODLService(lServices.Objects[i])); end; end; //WriteEmptyLine; Write('implementation'); WriteEmptyLine; Write('uses'); Write('{vcl:} SysUtils;',PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; for i := 0 to (aLibrary.ServiceCount-1) do WriteCoClass(aLibrary, aLibrary.Services[i]); Write('initialization'); {for i := 0 to (aLibrary.Count-1) do if (aLibrary.Items[i] is TRODLArray) or (aLibrary.Items[i] is TRODLStruct) then Write(' RegisterROClass('+aLibrary.Items[i].Name+');');} //WriteEmptyLine; {Write('finalization'); for i := 0 to (aLibrary.Count-1) do if (aLibrary.Items[i] is TRODLArray) or (aLibrary.Items[i] is TRODLStruct) then Write(' UnRegisterClass('+aLibrary.Items[i].Name+');'); WriteEmptyLine;} Write('end.'); finally end; end; class function TRODLToPascalAsync.GetTargetFileName(const aLibrary: TRODLLibrary; const aTargetEntity: string): string; begin try result := aLibrary.Name+'_Async.pas' except result := 'Unknown.pas'; end; end; const InnerIndent = 4; procedure TRODLToPascalAsync.WriteCoClass(aLibrary : TRODLLibrary; aService: TRODLService); var i, p : integer; sa : string; // soapsvc : boolean; begin if not aService.IsFromUsedRodl then with aService.Default do begin // soapsvc := IsSOAPService(aService); Write('{ Co'+aService.Name+' }'); WriteEmptyLine; Write(Format('class function Co%s_Async.Create(const aMessage: IROMessage; aTransportChannel: IROTransportChannel): I%s_Async;', [aService.Name, aService.Name])); Write('begin'); Write(Format(' result := T%s_AsyncProxy.Create(aMessage, aTransportChannel);', [aService.Name])); Write('end;'); WriteEmptyLine; if Count > 0 then begin Write(Format('{ T%s_AsyncProxy }', [aService.Name])); WriteEmptyLine; end; Write(Format('function T%s_AsyncProxy.__GetInterfaceName:string;',[aService.Name])); Write('begin'); Write(Format(' result := ''%s'';',[aService.Name])); Write('end;'); WriteEmptyLine; for i := 0 to (Count-1) do begin Write(GetAsyncInvokeOperationDefinition(Items[i], Format('T%s_AsyncProxy', [aService.Name]))); // Write('var __request:TStream;'); // if soapsvc then Write('var __http : IROHTTPTransport;'); Write('begin'); Write(Format('__AssertProxyNotBusy(''%s'');',[Items[i].Name]),PASCAL_INDENTATION_LEVEL_1); // Write('__request := TMemoryStream.Create;',PASCAL_INDENTATION_LEVEL_1); //Write('__response := TMemoryStream.Create;',PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; sa := GetAttributes(Items[i].Info.Attributes, aService.Info.Attributes, aLibrary.Info.Attributes, InnerIndent); if sa <> '' then Write('__Message.SetAttributes(__TransportChannel, '+sa+');', InnerIndent); Write(Format('__Message.InitializeRequestMessage(__TransportChannel, ''%s'', __InterfaceName, ''%s'');', [aLibrary.Name, Items[i].Name]), PASCAL_INDENTATION_LEVEL_1); with Items[i] do begin for p := 0 to (Count-1) do if IsInputFlag(Items[p].Flag) then begin if (StrToDataType(Items[p].DataType)=rtDateTime) then sa := '[paIsDateTime]' else sa := '[]'; Write(Format('__Message.Write(''%s'', TypeInfo(%s), %s, %s);', [Items[p].Name, GetDataType(Items[p].DataType), Items[p].Name, sa]), PASCAL_INDENTATION_LEVEL_1); end; end; // Write('__Message.Finalize;',PASCAL_INDENTATION_LEVEL_1); // WriteEmptyLine; // Write('__Message.WriteToStream(__request);',PASCAL_INDENTATION_LEVEL_1); if NeedsAsyncRetrieveOperationDefinition(Items[i]) then begin Write(Format('__DispatchAsyncRequest(''%s'',__Message);',[Items[i].Name]),PASCAL_INDENTATION_LEVEL_1); end else begin Write(Format('__DispatchAsyncRequest(''%s'',__Message, false);',[Items[i].Name]),PASCAL_INDENTATION_LEVEL_1); end; if sa <> '' then Write(' __Message.UnsetAttributes(__TransportChannel);'); Write('end;'); WriteEmptyLine; if NeedsAsyncRetrieveOperationDefinition(Items[i]) then begin Write(GetAsyncRetrieveOperationDefinition(Items[i], Format('T%s_AsyncProxy', [aService.Name]))); Write('var __response:TStream;'); Write('begin'); with Items[i] do begin for p := 0 to (Count-1) do if (Items[p].Flag in [fInOut,fOut]) and IsImplementedAsClass(Items[p].DataType, aLibrary) then Write(Format('%s := nil;', [Items[p].Name]),PASCAL_INDENTATION_LEVEL_1); if Assigned(Result) and IsImplementedAsClass(Result.DataType, aLibrary) then Write('result := nil;', PASCAL_INDENTATION_LEVEL_1); end; Write(Format('__response := __RetrieveAsyncResponse(''%s'');',[Items[i].Name]),PASCAL_INDENTATION_LEVEL_1); //Write('__TransportChannel.Dispatch(__request, __response);',PASCAL_INDENTATION_LEVEL_1); Write('__Message.ReadFromStream(__response);',PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; //Write(Format('Message.Initialize(''I%s'', ''%s'');', [aService.Name, Items[i].Name]), PASCAL_INDENTATION_LEVEL_1); with Items[i] do begin if Assigned(Result) then begin if (StrToDataType(Result.DataType)=rtDateTime) then sa := '[paIsDateTime]' else sa := '[]'; Write(Format('__Message.Read(''%s'', TypeInfo(%s), Result, %s);', [Result.Name, GetDataType(Result.DataType), sa]),PASCAL_INDENTATION_LEVEL_1); end; for p := 0 to (Count-1) do if IsOutputFlag(Items[p].Flag) then begin if (StrToDataType(Items[p].DataType)=rtDateTime) then sa := '[paIsDateTime]' else sa := '[]'; Write(Format('__Message.Read(''%s'', TypeInfo(%s), %s, %s);', [Items[p].Name, GetDataType(Items[p].DataType), Items[p].Name, sa]),PASCAL_INDENTATION_LEVEL_1); end; end; //Write('Message.Finalize;',5); //Write('__request.Free;',PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; Write('__response.Free();',PASCAL_INDENTATION_LEVEL_1); Write('end;'); WriteEmptyLine; end; end; WriteEmptyLine; end; end; { function TRODLToPascalAsync.IsSOAPService(aService: TRODLService): boolean; begin result := aService.Attributes.Values['Type'] = 'SOAP'; end; } procedure TRODLToPascalAsync.WriteServiceDeclarationCoClass( aService: TRODLService); //lOperation:TRODLOperation; begin if not aService.IsFromUsedRodl then with aService.Default do begin Write(Format('{ Co%s_Async }', [aService.Name]), PASCAL_INDENTATION_LEVEL_1); Write(Format('Co%s_Async = class', [aService.Name]), PASCAL_INDENTATION_LEVEL_1); Write(Format('class function Create(const aMessage: IROMessage; aTransportChannel: IROTransportChannel): I%s_Async;', [aService.Name]), PASCAL_INDENTATION_LEVEL_2); Write('end;', PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; end; end; procedure TRODLToPascalAsync.WriteServiceDeclarationInterface( aService: TRODLService); var i:integer; //lOperation:TRODLOperation; begin if not aService.IsFromUsedRodl then with aService.Default do begin Write(Format('{ I%s_Async }', [aService.Name]), PASCAL_INDENTATION_LEVEL_1); if aService.Ancestor <> '' then begin Write(Format('I%s_Async = interface(I%s_Async)', [aService.Name,aService.Ancestor]), PASCAL_INDENTATION_LEVEL_1); end else begin Write(Format('I%s_Async = interface(IROAsyncInterface)', [aService.Name]), PASCAL_INDENTATION_LEVEL_1); end; Write(Format('[''%s'']', [NewGuidAsString()]), PASCAL_INDENTATION_LEVEL_2); for i := 0 to (Count-1) do Write(GetAsyncInvokeOperationDefinition(Items[i]), PASCAL_INDENTATION_LEVEL_2); for i := 0 to (Count-1) do if NeedsAsyncRetrieveOperationDefinition(Items[i]) then Write(GetAsyncRetrieveOperationDefinition(Items[i]), PASCAL_INDENTATION_LEVEL_2); Write('end;', PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; end; end; procedure TRODLToPascalAsync.WriteServiceDeclarationProxy( aService: TRODLService); var i:integer; //lOperation:TRODLOperation; begin if not aService.IsFromUsedRodl then with aService.Default do begin Write(Format('{ T%s_AsyncProxy }', [aService.Name]), PASCAL_INDENTATION_LEVEL_1); if aService.Ancestor <> '' then begin Write(Format('T%s_AsyncProxy = class(T%s_AsyncProxy, I%s_Async)', [aService.Name, aService.Ancestor, aService.Name]),PASCAL_INDENTATION_LEVEL_1); end else begin Write(Format('T%s_AsyncProxy = class(TROAsyncProxy, I%s_Async)', [aService.Name, aService.Name]),PASCAL_INDENTATION_LEVEL_1); end; Write('private',PASCAL_INDENTATION_LEVEL_1); Write('protected',PASCAL_INDENTATION_LEVEL_1); Write(' function __GetInterfaceName:string; override;',PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; for i := 0 to (Count-1) do Write(GetAsyncInvokeOperationDefinition(Items[i]), PASCAL_INDENTATION_LEVEL_2); for i := 0 to (Count-1) do if NeedsAsyncRetrieveOperationDefinition(Items[i]) then Write(GetAsyncRetrieveOperationDefinition(Items[i]), PASCAL_INDENTATION_LEVEL_2); Write('end;',PASCAL_INDENTATION_LEVEL_1); WriteEmptyLine; end; end; end.