unit uRODLTemplateBasedConverter; {----------------------------------------------------------------------------} { RemObjects SDK Library - CodeGen2 } { } { 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 uRODLLineStream, uRODL, uROClasses, Classes, Contnrs; type // forward declarations TRODLTemplateBasedConverter = class; TServicesSectionClass = class of TServicesSection; TEventSinksSectionClass = class of TEventSinksSection; TBaseServiceSection = class; TBaseOperationSection = class; TParamsSection = class; TBaseStructSection = class; TFieldsSection = class; TArraysSection = class; TOutParamsSection = class; TOutParamsNoStripSection = class; TFieldSubSectionList = class; TProcedureOperationsSectionClass = class of TProcedureOperationsSection; TFunctionOperationsSectionClass = class of TFunctionOperationsSection; TOperationsSectionClass = class of TOperationsSection; TParamsNoStripSectionClass = class of TParamsNoStripSection; TStructsSectionClass = class of TStructsSection; TExceptionsSectionClass = class of TExceptionsSection; TRODLGeneratorSection = class private FParent: TRODLTemplateBasedConverter; protected FName: string; procedure Write(const line: string); procedure ProcessDocumentation(entity: TRODLEntity; const template: string); class procedure DoRODLEntityReplacements(var curLine: string; const aEntity: TRODLEntity; const Prefix: string); public constructor Create(AParent: TRODLTemplateBasedConverter; const AName: string); virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary); virtual; property Name: string read FName; property Parent: TRODLTemplateBasedConverter read FParent; end; TRODLGeneratorSectionList = class (TObjectList) private function GetItem(Index: Integer): TRODLGeneratorSection; procedure SetItem(Index: Integer; const Value: TRODLGeneratorSection); public function Add(AObject: TRODLGeneratorSection): Integer; property Items[Index: Integer]: TRODLGeneratorSection read GetItem write SetItem; default; end; TRODLTemplateBasedConverter = class (TRODLConverter) private FTemplateFileName: string; FSections: TRODLGeneratorSectionList; FUnitName: string; FFileExtension: string; function GetService(Index: Integer): TRODLService; function InternalSectionStart(const line: string; var section: TRODLGeneratorSection): Boolean; procedure SetupOrderedLists(const aLibrary: TRODLLibrary); function GetWriteDataModule: boolean; function GetUseDefaultAncestor: Boolean; protected FOrderedServices: IROStrings; FOrderedStructs: IROStrings; FOrderedExceptions: IROStrings; FOrderedEventSinks: IROStrings; FOrderedArrays: IROStrings; FOrderedEnums: IROStrings; FGlobalOrderedArrays: IROStrings; FGlobalOrderedEnums: IROStrings; FGlobalOrderedStructs: IROStrings; FLibrary: TRODLLibrary; FServerClassName: string; FRequiredUnits: string; procedure IntConvert(const aLibrary : TRODLLIbrary; const aTargetEntity : string = ''); override; function GetParamFrontModifier(flag: TRODLParamFlag): string; virtual; abstract; function GetParamBackModifier(flag: TRODLParamFlag): string; virtual; function GetTypeIdentifier(const originalType: string): string; virtual; abstract; procedure LoadTemplateFromResource(aTemplateStrings: TStrings; const AlternateTemplateName: string = ''); function GetTemplateResourceName(const aFileName: string): string; virtual; function GetUnitName: string; virtual; function GetNamespaceName(const aLibrary: TRODLLibrary): string; virtual; function GetFileExtension: string; virtual; function GetServicesSectionClass: TServicesSectionClass; virtual; function GetEventSinksSectionClass: TEventSinksSectionClass; virtual; function GetStructsSectionClass: TStructsSectionClass; virtual; function GetExceptionsSectionClass: TExceptionsSectionClass; virtual; procedure DoDefaultReplacements(var curLine: string; const aLibrary: TRODLLibrary); virtual; procedure SetupServices(const aLibrary: TRODLLibrary; const aTargetEntity : string = ''); virtual; procedure SetupRequiredUnits; virtual; procedure ProcessTemplate(const aLibrary: TRODLLibrary; template: TLineStream); virtual; property Sections: TRODLGeneratorSectionList read FSections; property Services[Index: Integer]: TRODLService read GetService; public constructor Create(const aLibrary: TRODLLibrary; const aTemplateFileName: string; const aUnitName: string; const aTargetEntity: string = ''); reintroduce; virtual; destructor Destroy; override; procedure SaveResultToFile(const FileName: string); virtual; procedure SaveResultToStream(const Stream: TStream); virtual; property TemplateFileName: string read FTemplateFileName write FTemplateFileName; property UnitName: string read GetUnitName write FUnitName; property FileExtension: string read GetFileExtension write FFileExtension; property RequiredUnits: string read FRequiredUnits write FRequiredUnits; property WriteDataModule: Boolean read GetWriteDataModule; property UseDefaultAncestor: Boolean read GetUseDefaultAncestor; property ServerClassName: string read FServerClassName write FServerClassName; // These ones apply to the current file. In split mode, they may well be empty property OrderedServices: IROStrings read FOrderedServices; property OrderedStructs: IROStrings read FOrderedStructs; property OrderedExceptions: IROStrings read FOrderedExceptions; property OrderedEventSinks: IROStrings read FOrderedEventSinks; property OrderedArrays: IROStrings read FOrderedArrays; property OrderedEnums: IROStrings read FOrderedEnums; // These ones apply to the entire library. In split mode, they may contain more than what's in the currently generated file property GlobalOrderedArrays: IROStrings read FGlobalOrderedArrays; property GlobalOrderedEnums: IROStrings read FGlobalOrderedEnums; property GlobalOrderedStructs: IROStrings read FGlobalOrderedStructs; end; TTemplatedSection = class (TRODLGeneratorSection) protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); virtual; abstract; public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary); override; end; TBaseServiceSubSection = class (TRODLGeneratorSection) private FParentSection: TBaseServiceSection; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection; const AName: string); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); reintroduce; virtual; property ParentSection: TBaseServiceSection read FParentSection; end; TTemplatedBaseServiceSubSection = class (TBaseServiceSubSection) protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); virtual; abstract; public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); override; end; TBaseServiceSubSectionList = class (TObjectList) private function GetItem(Index: Integer): TBaseServiceSubSection; procedure SetItem(Index: Integer; const Value: TBaseServiceSubSection); public function Add(AObject: TBaseServiceSubSection): Integer; property Items[Index: Integer]: TBaseServiceSubSection read GetItem write SetItem; default; end; TBaseProcedureSubSection = class (TRODLGeneratorSection) private FParentSection: TBaseOperationSection; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection; const AName: string); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); reintroduce; virtual; property ParentSection: TBaseOperationSection read FParentSection; end; TTemplatedBaseProcedureSubSection = class (TBaseProcedureSubSection) protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); virtual; abstract; public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; end; TBaseProcedureSubSectionList = class (TObjectList) private function GetItem(Index: Integer): TBaseProcedureSubSection; procedure SetItem(Index: Integer; const Value: TBaseProcedureSubSection); public function Add(AObject: TBaseProcedureSubSection): Integer; property Items[Index: Integer]: TBaseProcedureSubSection read GetItem write SetItem; default; end; TParamSubSection = class (TRODLGeneratorSection) private FParentSection: TParamsSection; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TParamsSection; const AName: string); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); reintroduce; virtual; property ParentSection: TParamsSection read FParentSection; end; TParamSubSectionList = class (TObjectList) private function GetItem(Index: Integer): TParamSubSection; procedure SetItem(Index: Integer; const Value: TParamSubSection); public function Add(AObject: TParamSubSection): Integer; property Items[Index: Integer]: TParamSubSection read GetItem write SetItem; default; end; TBaseStructSubSection = class (TRODLGeneratorSection) private FParentSection: TBaseStructSection; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection; const AName: string); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); reintroduce; virtual; property ParentSection: TBaseStructSection read FParentSection; end; TTemplatedBaseStructSubSection = class (TBaseStructSubSection) protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); virtual; abstract; public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); override; end; TBaseStructSubSectionList = class (TObjectList) private function GetItem(Index: Integer): TBaseStructSubSection; procedure SetItem(Index: Integer; const Value: TBaseStructSubSection); public function Add(AObject: TBaseStructSubSection): Integer; property Items[Index: Integer]: TBaseStructSubSection read GetItem write SetItem; default; end; TArraySubSection = class (TRODLGeneratorSection) private FParentSection: TArraysSection; protected function CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; virtual; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TArraysSection; const AName: string); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aArray: TRODLArray); reintroduce; virtual; property ParentSection: TArraysSection read FParentSection; end; TArraySubSectionList = class (TObjectList) private function GetItem(Index: Integer): TArraySubSection; procedure SetItem(Index: Integer; const Value: TArraySubSection); public function Add(AObject: TArraySubSection): Integer; property Items[Index: Integer]: TArraySubSection read GetItem write SetItem; default; end; TFieldSubSection = class (TRODLGeneratorSection) private FParentSection: TFieldsSection; protected function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; virtual; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TFieldsSection; const AName: string); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const IsLastField: Boolean); reintroduce; virtual; property ParentSection: TFieldsSection read FParentSection; end; TTemplatedFieldSubSection = class (TFieldSubSection) protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const IsLastField: Boolean); virtual; abstract; public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const IsLastField: Boolean); override; end; TFieldSubSectionList = class (TObjectList) private function GetItem(Index: Integer): TFieldSubSection; procedure SetItem(Index: Integer; const Value: TFieldSubSection); public function Add(AObject: TFieldSubSection): Integer; property Items[Index: Integer]: TFieldSubSection read GetItem write SetItem; default; end; // Base classes TBaseStructSection = class (TTemplatedSection) private protected FSections: TBaseStructSubSectionList; property Sections: TBaseStructSubSectionList read FSections; function InternalSectionStart(const line: string; var section: TBaseStructSubSection): Boolean; function GetAncestorName(const aStruct: TRODLBaseStruct): string; virtual; abstract; function GetEntityPrefix: string; virtual; abstract; function GetStructList: IROStrings; virtual; abstract; function GetAncestorCollectionName(const aStruct: TRODLBaseStruct): string; procedure DoReplacements(var curLine: string; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); virtual; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AName: string); override; destructor Destroy; override; end; TBaseServiceSection = class (TTemplatedSection) protected FSections: TBaseServiceSubSectionList; function InternalSectionStart(const line: string; var section: TBaseServiceSubSection): Boolean; property Sections: TBaseServiceSubSectionList read FSections; function GetAncestorName(const aService: TRODLBaseService): string; virtual; function GetEntityPrefix: string; virtual; abstract; function GetServiceList: IROStrings; virtual; abstract; procedure DoReplacements(var curLine: string; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); virtual; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AName: string); override; destructor Destroy; override; end; TBaseOperationSection = class (TTemplatedBaseServiceSubSection) protected FSections: TBaseProcedureSubSectionList; function InternalSectionStart(const line: string; var section: TBaseProcedureSubSection): Boolean; property Sections: TBaseProcedureSubSectionList read FSections; function GetParamsNoStripSectionClass: TParamsNoStripSectionClass; virtual; function OperationApplies(aOperation: TRODLOperation): Boolean; virtual; abstract; procedure DoReplacements(var curLine: string; const aOperation: TRODLOperation; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); virtual; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection; const AName: string); override; destructor Destroy; override; end; // REQUIRED_UNITS TRequiredUnitsSection = class (TRODLGeneratorSection) protected procedure DoReplacements(var curLine: string; const unitName: string; const aLibrary: TRODLLibrary); dynamic; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary); override; end; // USED_RODLS TUsedRODLsSection = class (TRODLGeneratorSection) protected procedure DoReplacements(var curLine: string; unitName: string; const aLibrary: TRODLLibrary); dynamic; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary); override; end; // SERVICES TServicesSection = class (TBaseServiceSection) protected function GetEntityPrefix: string; override; function GetServiceList: IROStrings; override; function IsSOAPService(const aService : TRODLBaseService) : Boolean; function GetProxyAncestorName(const aService: TRODLBaseService): string; virtual; function GetInvokerAncestorName(const aService: TRODLBaseService): string; virtual; function GetProxySuffix: string; virtual; function GetProcedureOperationsSectionClass: TProcedureOperationsSectionClass; virtual; function GetFunctionOperationsSectionClass: TFunctionOperationsSectionClass; virtual; procedure DoReplacements(var curLine: string; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); override; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; end; // ENUMS TEnumsSection = class (TTemplatedSection) protected procedure ProcessValues(enum: TRODLEnum; const template: string); procedure DoReplacements(var curLine: string; aEnum: TRODLEnum; const aLibrary: TRODLLibrary); dynamic; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); override; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; class function GetEnumValueName(const enum: TRODLEnum; const ValueIndex: Integer): string; end; // EVENT_SINKS TEventSinksSection = class (TBaseServiceSection) protected function GetEntityPrefix: string; override; function GetServiceList: IROStrings; override; function GetEventSinkWriterAncestorName(const aEventSink: TRODLEventSink): string; dynamic; function GetEventSinkInvokerAncestorName(const aEventSink: TRODLEventSink): string; dynamic; function GetOperationsSectionClass: TOperationsSectionClass; virtual; procedure DoReplacements(var curLine: string; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); override; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; end; // ARRAYS TArraysSection = class (TTemplatedSection) protected FSections: TArraySubSectionList; function InternalSectionStart(const line: string; var section: TArraySubSection): Boolean; property Sections: TArraySubSectionList read FSections; procedure DoReplacements(var curLine: string; const aArray: TRODLArray; const aLibrary: TRODLLibrary); virtual; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); override; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; destructor Destroy; override; end; // STRUCTS TStructsSection = class (TBaseStructSection) protected function GetEntityPrefix: string; override; function GetAncestorName(const aStruct: TRODLBaseStruct): string; override; function GetStructList: IROStrings; override; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; end; // EXCEPTIONS TExceptionsSection = class (TBaseStructSection) protected function GetEntityPrefix: string; override; function GetAncestorName(const aStruct: TRODLBaseStruct): string; override; function GetStructList: IROStrings; override; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; end; // OPERATIONS TOperationsSection = class (TBaseOperationSection) protected function OperationApplies(aOperation: TRODLOperation): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); reintroduce; virtual; end; // PROCEDURE_OPERATIONS TProcedureOperationsSection = class (TBaseOperationSection) protected function OperationApplies(aOperation: TRODLOperation): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); reintroduce; virtual; end; // FUNCTION_OPERATIONS TFunctionOperationsSection = class (TBaseOperationSection) protected function OperationApplies(aOperation: TRODLOperation): Boolean; override; procedure DoReplacements(var curLine: string; const aOperation: TRODLOperation; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); reintroduce; virtual; end; // PARAMS TParamsSection = class (TTemplatedBaseProcedureSubSection) private protected FSections: TParamSubSectionList; function InternalSectionStart(const line: string; var section: TParamSubSection): Boolean; property Sections: TParamSubSectionList read FSections; procedure EnsureStripping(var curLine: string; IsLastParam: Boolean); procedure DoReplacements(var curLine: string; const aParameter: TRODLOperationParam; const aLibrary: TRODLLibrary); virtual; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; function CanStrip: Boolean; virtual; function CanUse(const AParam: TRODLOperationParam): Boolean; virtual; class function GetAttributeReplacement(const dataType: string): string; virtual; public class procedure DoAttributeReplacements(var curLine: string; const dataType: string; const prefix: string); constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); reintroduce; virtual; destructor Destroy; override; end; // PARAMS_NO_STRIP TParamsNoStripSection = class (TParamsSection) protected function CanStrip: Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); override; end; // IF_PARAM_TYPE_COMPLEX TIfParamTypeComplexSection = class (TParamSubSection) public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); override; constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection); reintroduce; virtual; end; // IF_PARAM_TYPE_SIMPLE TIfParamTypeSimpleSection = class (TParamSubSection) public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); override; constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection); reintroduce; virtual; end; // IF_PARAM_XXXX_TYPE TIfParamXXXTypeSection = class (TParamSubSection) protected FDataType: string; public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); override; constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection; const DataType: string); reintroduce; virtual; end; // IF_PARAM_OTHER_TYPE TIfParamOtherTypeSection = class (TParamSubSection) public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); override; constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection); reintroduce; virtual; end; // IF_STRUCT_HAS_ANCESTOR TIfStructHasAncestor = class(TBaseStructSubSection) public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); override; end; // FIELDS TFieldsSection = class (TTemplatedBaseStructSubSection) private protected FSections: TFieldSubSectionList; function InternalSectionStart(const line: string; var section: TFieldSubSection): Boolean; property Sections: TFieldSubSectionList read FSections; function CanStrip: Boolean; virtual; procedure EnsureStripping(var curLine: string; IsLastField: Boolean); procedure DoReplacements(var curLine: string; curField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); procedure ProcessField(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; AField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; IsLastField: Boolean); virtual; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); reintroduce; virtual; destructor Destroy; override; end; // FIELDS_NO_STRIP TFieldsNoStripSection = class (TFieldsSection) protected function CanStrip: Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); override; end; // ANCESTOR_FIELDS TAncestorFieldsSection = class (TFieldsSection) protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); override; function CanStrip: Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); override; end; // ENTIRE_HIERARCHY_FIELDS TEntireHierarchyFieldsSection = class (TFieldsSection) protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); override; function CanStrip: Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); override; end; // IF_FIELD_XXXX_TYPE TIfFieldXXXTypeSection = class (TFieldSubSection) protected FDataType: string; function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection; const DataType: string); reintroduce; virtual; end; // IF_FIELD_ARRAY_TYPE TIfFieldArrayTypeSection = class (TFieldSubSection) protected function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_FIELD_ENUM_TYPE TIfFieldEnumTypeSection = class (TFieldSubSection) protected function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_FIELD_STRUCT_TYPE TIfFieldStructTypeSection = class (TFieldSubSection) protected function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_FIELD_TYPE_COMPLEX TIfFieldTypeComplexSection = class (TTemplatedFieldSubSection) protected FSections: TFieldSubSectionList; function InternalSectionStart(const line: string; var section: TFieldSubSection): Boolean; property Sections: TFieldSubSectionList read FSections; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const IsLastField: Boolean); override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; destructor Destroy; override; end; // IF_AUTO_CREATE_FIELDS TIfAutoCreateFieldsSection = class (TFieldSubSection) protected function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_NOT_AUTO_CREATE_FIELDS TIfNotAutoCreateFieldsSection = class (TFieldSubSection) protected function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_FIELD_TYPE_SIMPLE TIfFieldTypeSimpleSection = class (TFieldSubSection) protected function CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_STRING_FIELD TIfStringFieldSection = class (TIfFieldXXXTypeSection) public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_CURRENCY_FIELD TIfCurrencyFieldSection = class (TIfFieldXXXTypeSection) public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_DECIMAL_FIELD TIfDecimalFieldSection = class (TIfFieldXXXTypeSection) public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_VARIANT_FIELD TIfVariantFieldSection = class (TIfFieldXXXTypeSection) public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); reintroduce; virtual; end; // IF_HAS_FIELDS TIfHasFieldsSection = class (TTemplatedBaseStructSubSection) private FSections: TBaseStructSubSectionList; function InternalSectionStart(const line: string; var section: TBaseStructSubSection): Boolean; protected procedure DoReplacements(var curLine: string; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); reintroduce; virtual; destructor Destroy; override; end; // IF_DATA_MODULE TIfDataModuleSection = class (TRODLGeneratorSection) public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary); override; end; // IF_DATA_MODULE (inside a SERVICES section) TIfDataModuleServiceSection = class (TBaseServiceSubSection) public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); override; end; // IF_HYDRA TIfHydraSection = class (TRODLGeneratorSection) private FIsHydraModule: Boolean; public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary); override; end; // IF_WSDL TIfWSDLSection = class (TRODLGeneratorSection) public constructor Create(AParent: TRODLTemplateBasedConverter); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary); override; end; // ANCESTOR_SERVICES TAncestorServicesSection = class (TBaseServiceSubSection) public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); reintroduce; virtual; procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); override; end; // IF_HAS_COMPLEX_TYPE TIfHasComplexTypeSection = class (TTemplatedBaseProcedureSubSection) private FSections: TBaseProcedureSubSectionList; function InternalSectionStart(const line: string; var section: TBaseProcedureSubSection): Boolean; property Sections: TBaseProcedureSubSectionList read FSections; function OperationHasComplexType(const aOperation: TRODLOperation; const aLibrary: TRODLLibrary): Boolean; protected procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); reintroduce; virtual; destructor Destroy; override; end; // IF_ARRAY_TYPE_SIMPLE TIfArrayTypeSimpleSection = class (TArraySubSection) protected function CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TArraysSection); reintroduce; virtual; end; // IF_ARRAY_TYPE_COMPLEX TIfArrayTypeComplexSection = class (TArraySubSection) protected function CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TArraysSection); reintroduce; virtual; end; // IF_ARRAY_XXXX_TYPE TIfArrayXXXTypeSection = class (TArraySubSection) protected FDataType: string; function CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection; const DataType: string); reintroduce; virtual; end; // IF_ARRAY_ARRAY_TYPE TIfArrayArrayTypeSection = class (TArraySubSection) protected function CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection); reintroduce; virtual; end; // IF_ARRAY_ENUM_TYPE TIfArrayEnumTypeSection = class (TArraySubSection) protected function CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection); reintroduce; virtual; end; // IF_ARRAY_STRUCT_TYPE TIfArrayStructTypeSection = class (TArraySubSection) protected function CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection); reintroduce; virtual; end; // IN_PARAMS TInParamsSection = class (TParamsSection) protected function CanUse(const AParam: TRODLOperationParam): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); override; end; // IN_PARAMS_NO_STRIP TInParamsNoStripSection = class (TInParamsSection) protected function CanStrip: Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); override; end; // OUT_PARAMS TOutParamsSection = class (TParamsSection) protected function CanUse(const AParam: TRODLOperationParam): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); override; end; // OUT_PARAMS_NO_STRIP TOutParamsNoStripSection = class (TOutParamsSection) protected function CanStrip: Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); override; end; // IF_OUT_PARAMS TIfOutParamsSection = class (TTemplatedBaseProcedureSubSection) protected FSections: TBaseProcedureSubSectionList; function InternalSectionStart(const line: string; var section: TBaseProcedureSubSection): Boolean; property Sections: TBaseProcedureSubSectionList read FSections; function CanUse(const aOperation: TRODLOperation): Boolean; virtual; procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); reintroduce; virtual; destructor Destroy; override; end; // IF_NO_OUT_PARAMS TIfNoOutParamsSection = class (TIfOutParamsSection) protected function CanUse(const aOperation: TRODLOperation): Boolean; override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); override; end; // IF_RESULT_COMPLEX TIfResultComplexSection = class (TBaseProcedureSubSection) public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); reintroduce; virtual; end; // IF_RESULT_SIMPLE TIfResultSimpleSection = class (TBaseProcedureSubSection) public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); reintroduce; virtual; end; // IF_RESULT_XXXX_TYPE TIfResultXXXTypeSection = class (TBaseProcedureSubSection) protected FDataType: string; public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection; const DataType: string); reintroduce; virtual; end; // IF_RESULT_OTHER_TYPE TIfResultOtherTypeSection = class (TBaseProcedureSubSection) public procedure Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); override; constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); reintroduce; virtual; end; // ARRAYS_IS_FOUND TArraysIsFound = class (TTemplatedBaseStructSubSection) protected procedure DoReplacements(var curLine: string; const aArray: TRODLArray; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); procedure ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); override; public constructor Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); reintroduce; virtual; end; implementation uses {$IFDEF MSWINDOWS}Windows,{$ENDIF} {$IFDEF LINUX}Types,Libc,{$ENDIF} {$IFDEF HYDRA_DESIGNTIME}uEWOTAHelpers,{$ENDIF} uRODLTemplateBasedConverterUtils, SysUtils, uROServer, uROTypes, uROSerializer; function IsHydraModule : boolean; {$IFDEF HYDRA_DESIGNTIME} var lSource: string; {$ENDIF HYDRA_DESIGNTIME} begin Result := False; {$IFDEF HYDRA_DESIGNTIME} if (CurrentProject<>NIL) then begin lSource := UpperCase(ReadModuleSource(CurrentProject)); Result := Pos('{#HYDRAMODULE}', lSource)>0; end; {$ENDIF HYDRA_DESIGNTIME} end; { TRODLTemplateBasedConverter } constructor TRODLTemplateBasedConverter.Create(const aLibrary: TRODLLibrary; const aTemplateFileName: string; const aUnitName: string; const aTargetEntity: string); begin inherited Create(aLibrary, aTargetEntity); FTemplateFileName := ATemplateFileName; FUnitName := aUnitName; FSections := TRODLGeneratorSectionList.Create(True); // Adding the generic sections FSections.Add(TRequiredUnitsSection.Create(Self)); FSections.Add(TUsedRODLsSection.Create(Self)); FSections.Add(GetServicesSectionClass.Create(Self)); FSections.Add(TEnumsSection.Create(Self)); FSections.Add(GetEventSinksSectionClass.Create(Self)); FSections.Add(TArraysSection.Create(Self)); FSections.Add(GetStructsSectionClass.Create(Self)); FSections.Add(GetExceptionsSectionClass.Create(Self)); FSections.Add(TIfDataModuleSection.Create(Self)); FSections.Add(TIfHydraSection.Create(Self)); end; destructor TRODLTemplateBasedConverter.Destroy; begin FSections.Free; inherited Destroy; end; procedure TRODLTemplateBasedConverter.ProcessTemplate(const aLibrary: TRODLLibrary; template: TLineStream); var curLine: string; section: TRODLGeneratorSection; begin while not Template.Eof do begin curLine := Template.ReadLine; DoDefaultReplacements(curLine, aLibrary); // Line that start a section if InternalSectionStart(curLine, section) then begin section.Process(FinishSection(section.Name, template), aLibrary); end else // regular line begin Write(curLine); end; end; end; procedure TRODLTemplateBasedConverter.DoDefaultReplacements(var curLine: string; const aLibrary: TRODLLibrary); begin // Default macros TRODLGeneratorSection.DoRODLEntityReplacements(curLine, aLibrary, 'LIBRARY'); MacroReplace(curLine, '%', ['UNIT_NAME', GetUnitName, 'NAMESPACE_NAME', GetNamespaceName(aLibrary) ]); end; function TRODLTemplateBasedConverter.InternalSectionStart(const line: string; var section: TRODLGeneratorSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TRODLTemplateBasedConverter.LoadTemplateFromResource(aTemplateStrings: TStrings; const AlternateTemplateName: string = ''); var templateStream: TResourceStream; usedTemplateName: string; begin if Assigned(aTemplateStrings) then begin if Length(AlternateTemplateName) > 0 then usedTemplateName := AlternateTemplateName else usedTemplateName := TemplateFileName; templateStream := TResourceStream.Create(hInstance, GetTemplateResourceName(usedTemplateName), RT_RCDATA); try aTemplateStrings.LoadFromStream(templateStream); finally templateStream.Free; end; end; end; function TRODLTemplateBasedConverter.GetEventSinksSectionClass: TEventSinksSectionClass; begin Result := TEventSinksSection; end; function TRODLTemplateBasedConverter.GetExceptionsSectionClass: TExceptionsSectionClass; begin Result := TExceptionsSection; end; function TRODLTemplateBasedConverter.GetFileExtension: string; begin Result := FFileExtension; end; function TRODLTemplateBasedConverter.GetNamespaceName( const aLibrary: TRODLLibrary): string; begin Result := aLibrary.Namespace; if Length(Result) = 0 then Result := aLibrary.Name; end; function TRODLTemplateBasedConverter.GetParamBackModifier( flag: TRODLParamFlag): string; begin Result := ''; end; function TRODLTemplateBasedConverter.GetService(Index: Integer): TRODLService; begin Result := FOrderedServices.Objects[Index] as TRODLService; end; function TRODLTemplateBasedConverter.GetServicesSectionClass: TServicesSectionClass; begin Result := TServicesSection; end; function TRODLTemplateBasedConverter.GetStructsSectionClass: TStructsSectionClass; begin Result := TStructsSection; end; function TRODLTemplateBasedConverter.GetTemplateResourceName( const aFileName: string): string; begin // By default, return the file name without its path part replacing dots // and spaces by an underscore, all this uppercased Result := ExtractFileName(aFileName); Result := StringReplace(Result, '.', '_', [rfReplaceAll]); Result := StringReplace(Result, ' ', '_', [rfReplaceAll]); Result := UpperCase(Result); end; function TRODLTemplateBasedConverter.GetUnitName: string; begin Result := FUnitName; end; function TRODLTemplateBasedConverter.GetUseDefaultAncestor: Boolean; begin Result := SameText(ServerClassName, TRORemotable.ClassName); end; function TRODLTemplateBasedConverter.GetWriteDataModule: boolean; begin Result := not UseDefaultAncestor; end; procedure TRODLTemplateBasedConverter.IntConvert(const aLibrary: TRODLLIbrary; const aTargetEntity: string); var templateContent: TStringList; template: TLineStream; begin FLibrary := aLibrary; SetupServices(aLibrary); SetupOrderedLists(aLibrary); template := TLineStream.Create(''); try // Read template content templateContent := TStringList.Create; try if FileExists(TemplateFileName) then templateContent.LoadFromFile(TemplateFileName) else LoadTemplateFromResource(templateContent); template.WriteString(templateContent.Text); template.Position := 0; finally templateContent.Free; end; // Process it ProcessTemplate(aLibrary, template); finally template.Free; end; end; procedure TRODLTemplateBasedConverter.SaveResultToFile(const FileName: string); begin Buffer.SaveToFile(FileName); end; procedure TRODLTemplateBasedConverter.SaveResultToStream(const Stream: TStream); begin Buffer.SaveToStream(Stream); end; procedure TRODLTemplateBasedConverter.SetupOrderedLists(const aLibrary: TRODLLibrary); var I: Integer; begin FOrderedStructs := aLibrary.CalcStructOrder; FOrderedExceptions := aLibrary.CalcExceptionOrder; FOrderedEventSinks := aLibrary.CalcEventSinkOrder; //ToDo : This should use a CalcArraysOrder method which is currently not present in uRODL.pas FOrderedArrays := NewROStrings(); for I := 0 to aLibrary.ArrayCount-1 do begin if not aLibrary.Arrays[i].IsFromUsedRodl then FOrderedArrays.AddObject(aLibrary.Arrays[i].Info.Name, aLibrary.Arrays[i]); end; //ToDo : This should use a CalcEnumsOrder method which is currently not present in uRODL.pas FOrderedEnums := NewROStrings(); for I := 0 to aLibrary.EnumCount-1 do begin if not aLibrary.Enums[i].IsFromUsedRodl then FOrderedEnums.AddObject(aLibrary.Enums[i].Info.Name, aLibrary.Enums[i]); end; FGlobalOrderedStructs := NewROStrings(); FGlobalOrderedStructs.AddStrings(FOrderedStructs.Strings); FGlobalOrderedArrays := NewROStrings(); FGlobalOrderedArrays.AddStrings(FOrderedArrays.Strings); FGlobalOrderedEnums := NewROStrings(); FGlobalOrderedEnums.AddStrings(FOrderedEnums.Strings); end; procedure TRODLTemplateBasedConverter.SetupRequiredUnits; begin // nothing to do by default. end; procedure TRODLTemplateBasedConverter.SetupServices( const aLibrary: TRODLLibrary; const aTargetEntity : string = ''); var I: Integer; orderedServices: IROStrings; curService: TRODLService; begin if not Assigned(FOrderedServices) then FOrderedServices := NewROStrings() else FOrderedServices.Clear; // By default, all the services of the library are of interest to us orderedServices := aLibrary.CalcServiceOrder; for I := 0 to orderedServices.Count - 1 do begin curService := orderedServices.Objects[I] as TRODLService; if not curService.IsFromUsedRodl then FOrderedServices.AddObject(curService.Name, curService); end; end; { TRODLGeneratorSection } constructor TRODLGeneratorSection.Create(AParent: TRODLTemplateBasedConverter; const AName: string); begin inherited Create; FParent := AParent; FName := AName; end; class procedure TRODLGeneratorSection.DoRODLEntityReplacements(var curLine: string; const aEntity: TRODLEntity; const Prefix: string); begin MacroReplace(curLine, '%', [Prefix + '_NAME', aEntity.Name, Prefix + '_UID', GUIDToString(aEntity.UID) ]); end; procedure TRODLGeneratorSection.Process(const sectionText: string; const aLibrary: TRODLLibrary); begin Write(sectionText); end; procedure TRODLGeneratorSection.ProcessDocumentation(entity: TRODLEntity; const template: string); var curLine: string; content: string; begin content := Trim(entity.Documentation); if Length(content) > 0 then begin curLine := template; MacroReplace(curLine, '%', ['CONTENT', content ]); Write(curLine); end; end; procedure TRODLGeneratorSection.Write(const line: string); begin Parent.Write(line); end; { TRODLGeneratorSectionList } function TRODLGeneratorSectionList.Add(AObject: TRODLGeneratorSection): Integer; begin Result := inherited Add(AObject); end; function TRODLGeneratorSectionList.GetItem(Index: Integer): TRODLGeneratorSection; begin Result := inherited Items[Index] as TRODLGeneratorSection; end; procedure TRODLGeneratorSectionList.SetItem(Index: Integer; const Value: TRODLGeneratorSection); begin inherited Items[Index] := Value; end; { TTemplatedSection } procedure TTemplatedSection.Process(const sectionText: string; const aLibrary: TRODLLibrary); var sectionTemplate: TLineStream; begin sectionTemplate := TLineStream.Create(sectionText); try ProcessTemplate(sectionTemplate, aLibrary); finally sectionTemplate.Free; end; end; { TServiceSection } constructor TBaseServiceSubSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection; const AName: string); begin inherited Create(AParent, AName); FParentSection := AParentSection; end; procedure TBaseServiceSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); begin inherited Process(sectionText, aLibrary); end; { TTemplatedServiceSection } procedure TTemplatedBaseServiceSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); var sectionTemplate: TLineStream; begin sectionTemplate := TLineStream.Create(sectionText); try ProcessTemplate(sectionTemplate, aLibrary, aService); finally sectionTemplate.Free; end; end; { TServiceSectionList } function TBaseServiceSubSectionList.Add(AObject: TBaseServiceSubSection): Integer; begin Result := inherited Add(AObject); end; function TBaseServiceSubSectionList.GetItem(Index: Integer): TBaseServiceSubSection; begin Result := inherited Items[Index] as TBaseServiceSubSection; end; procedure TBaseServiceSubSectionList.SetItem(Index: Integer; const Value: TBaseServiceSubSection); begin inherited Items[Index] := Value; end; { TProcedureSubSection } constructor TBaseProcedureSubSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection; const AName: string); begin inherited Create(AParent, AName); FParentSection := AParentSection; end; procedure TBaseProcedureSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); begin inherited Process(sectionText, aLibrary); end; { TTemplatedProcedureSubSection } procedure TTemplatedBaseProcedureSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var sectionTemplate: TLineStream; begin sectionTemplate := TLineStream.Create(sectionText); try ProcessTemplate(sectionTemplate, aLibrary, aOperation, aService); finally sectionTemplate.Free; end; end; { TProcedureSubSectionList } function TBaseProcedureSubSectionList.Add(AObject: TBaseProcedureSubSection): Integer; begin Result := inherited Add(AObject); end; function TBaseProcedureSubSectionList.GetItem(Index: Integer): TBaseProcedureSubSection; begin Result := inherited Items[Index] as TBaseProcedureSubSection; end; procedure TBaseProcedureSubSectionList.SetItem(Index: Integer; const Value: TBaseProcedureSubSection); begin inherited Items[Index] := Value; end; { TParamSubSection } constructor TParamSubSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TParamsSection; const AName: string); begin inherited Create(AParent, AName); FParentSection := AParentSection; end; procedure TParamSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); var curLine: string; begin curLine := sectionText; ParentSection.DoReplacements(curLine, aParameter, aLibrary); ParentSection.EnsureStripping(curLine, IsLastParam); inherited Process(curLine, aLibrary); end; { TParamSubSectionList } function TParamSubSectionList.Add(AObject: TParamSubSection): Integer; begin Result := inherited Add(AObject); end; function TParamSubSectionList.GetItem(Index: Integer): TParamSubSection; begin Result := inherited Items[Index] as TParamSubSection; end; procedure TParamSubSectionList.SetItem(Index: Integer; const Value: TParamSubSection); begin inherited Items[Index] := Value; end; { TStructSubSection } constructor TBaseStructSubSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection; const AName: string); begin inherited Create(AParent, AName); FParentSection := AParentSection; end; procedure TBaseStructSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); begin inherited Process(sectionText, aLibrary); end; { TTemplatedStructSubSection } procedure TTemplatedBaseStructSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); var sectionTemplate: TLineStream; begin sectionTemplate := TLineStream.Create(sectionText); try ProcessTemplate(sectionTemplate, aLibrary, aStruct); finally sectionTemplate.Free; end; end; { TStructSubSectionList } function TBaseStructSubSectionList.Add(AObject: TBaseStructSubSection): Integer; begin Result := inherited Add(AObject); end; function TBaseStructSubSectionList.GetItem(Index: Integer): TBaseStructSubSection; begin Result := inherited Items[Index] as TBaseStructSubSection; end; procedure TBaseStructSubSectionList.SetItem(Index: Integer; const Value: TBaseStructSubSection); begin inherited Items[Index] := Value; end; { TFieldSubSection } function TFieldSubSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := True; end; constructor TFieldSubSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TFieldsSection; const AName: string); begin inherited Create(AParent, AName); FParentSection := AParentSection; end; procedure TFieldSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const IsLastField: Boolean); var curLine: string; begin if CanUse(aField, aStruct) then begin curLine := sectionText; ParentSection.DoReplacements(curLine, aField, aStruct, aLibrary); ParentSection.EnsureStripping(curLine, IsLastField); inherited Process(curLine, aLibrary); end; end; { TTemplatedFieldSubSection } procedure TTemplatedFieldSubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const IsLastField: Boolean); var sectionTemplate: TLineStream; begin if CanUse(aField, aStruct) then begin sectionTemplate := TLineStream.Create(sectionText); try ProcessTemplate(sectionTemplate, aLibrary, aField, aStruct, IsLastField); finally sectionTemplate.Free; end; end; end; { TFieldSubSectionList } function TFieldSubSectionList.Add(AObject: TFieldSubSection): Integer; begin Result := inherited Add(AObject); end; function TFieldSubSectionList.GetItem(Index: Integer): TFieldSubSection; begin Result := inherited Items[Index] as TFieldSubSection; end; procedure TFieldSubSectionList.SetItem(Index: Integer; const Value: TFieldSubSection); begin inherited Items[Index] := Value; end; { TArraySubSection } function TArraySubSection.CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; begin Result := True; end; constructor TArraySubSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TArraysSection; const AName: string); begin inherited Create(AParent, AName); FParentSection := AParentSection; end; procedure TArraySubSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aArray: TRODLArray); var curLine: string; begin if CanUse(aArray, aLibrary) then begin curLine := sectionText; ParentSection.DoReplacements(curLine, aArray, aLibrary); inherited Process(curLine, aLibrary); end; end; { TArraySubSectionList } function TArraySubSectionList.Add(AObject: TArraySubSection): Integer; begin Result := inherited Add(AObject); end; function TArraySubSectionList.GetItem(Index: Integer): TArraySubSection; begin Result := inherited Items[Index] as TArraySubSection; end; procedure TArraySubSectionList.SetItem(Index: Integer; const Value: TArraySubSection); begin inherited Items[Index] := Value; end; { TBaseStructSection } constructor TBaseStructSection.Create(AParent: TRODLTemplateBasedConverter; const AName: string); begin inherited Create(AParent, AName); FSections := TBaseStructSubSectionList.Create(True); FSections.Add(TIfStructHasAncestor.Create(AParent, Self)); FSections.Add(TFieldsSection.Create(AParent, Self)); FSections.Add(TFieldsNoStripSection.Create(AParent, Self)); FSections.Add(TIfHasFieldsSection.Create(AParent, Self)); FSections.Add(TAncestorFieldsSection.Create(AParent, Self)); FSections.Add(TEntireHierarchyFieldsSection.Create(AParent, Self)); end; destructor TBaseStructSection.Destroy; begin FSections.Free; inherited Destroy; end; function TBaseStructSection.InternalSectionStart(const line: string; var section: TBaseStructSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TBaseStructSection.DoReplacements(var curLine: string; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); begin Parent.DoDefaultReplacements(curLine, aLibrary); DoRODLEntityReplacements(curLine, aStruct, GetEntityPrefix); MacroReplace(curLine, '%', [GetEntityPrefix + '_ANCESTOR_NAME', GetAncestorName(aStruct) ]); // Note: this might be better moved to the "Delphi" classes as Collection // is a Delphi specific, AFAIK MacroReplace(curLine, '%', [GetEntityPrefix + '_COLLECTION_NAME', aStruct.Name + COLLECTION_SUFFIX, GetEntityPrefix + '_ANCESTOR_COLLECTION_NAME', GetAncestorCollectionName(aStruct) ]); end; function TBaseStructSection.GetAncestorCollectionName( const aStruct: TRODLBaseStruct): string; begin Result := aStruct.Ancestor; if Length(Result) = 0 then Result := DEFAULT_STRUCT_COLLECTION_ANCESTOR else Result := Result + COLLECTION_SUFFIX; end; procedure TBaseStructSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); var I: Integer; curStruct: TRODLBaseStruct; curLine: string; section: TBaseStructSubSection; begin for I := 0 to GetStructList.Count - 1 do begin curStruct := GetStructList.Objects[I] as TRODLBaseStruct; if not curStruct.IsFromUsedRodl then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, curStruct, aLibrary); if InternalSectionStart(curLine, section) then begin section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, curStruct); end else if SectionStart(curLine, 'DOCUMENTATION') then ProcessDocumentation(curStruct, FinishSection('DOCUMENTATION', sectionTemplate)) else Write(curLine); end; end; end; end; { TBaseServiceSection } constructor TBaseServiceSection.Create(AParent: TRODLTemplateBasedConverter; const AName: string); begin inherited Create(AParent, AName); FSections := TBaseServiceSubSectionList.Create(True); // Adding the sub sections FSections.Add(TIfDataModuleServiceSection.Create(AParent, Self)); FSections.Add(TAncestorServicesSection.Create(AParent, Self)); end; destructor TBaseServiceSection.Destroy; begin FSections.Free; inherited Destroy; end; procedure TBaseServiceSection.DoReplacements(var curLine: string; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); begin Parent.DoDefaultReplacements(curLine, aLibrary); DoRODLEntityReplacements(curLine, aService, GetEntityPrefix); MacroReplace(curLine, '%', [GetEntityPrefix + '_ANCESTOR_NAME', GetAncestorName(aService) ]); end; function TBaseServiceSection.GetAncestorName( const aService: TRODLBaseService): string; begin Result := aService.Ancestor; end; function TBaseServiceSection.InternalSectionStart(const line: string; var section: TBaseServiceSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TBaseServiceSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); var I: Integer; curService: TRODLBaseService; curLine: string; section: TBaseServiceSubSection; begin for I := 0 to GetServiceList.Count - 1 do begin curService := GetServiceList.Objects[I] as TRODLBaseService; if Assigned(curService.Default) then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, curService, aLibrary); if InternalSectionStart(curLine, section) then begin section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, curService); end else if SectionStart(curLine, 'DOCUMENTATION') then begin ProcessDocumentation(curService, FinishSection('DOCUMENTATION', sectionTemplate)) end else begin Write(curLine); end; end; end; end; end; { TBaseOperationSection } constructor TBaseOperationSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection; const AName: string); var DataType: TRODataType; begin inherited Create(AParent, AParentSection, AName); FSections := TBaseProcedureSubSectionList.Create(True); // Add subsections FSections.Add(TParamsSection.Create(AParent, Self)); FSections.Add(GetParamsNoStripSectionClass.Create(AParent, Self)); FSections.Add(TInParamsSection.Create(AParent, Self)); FSections.Add(TInParamsNoStripSection.Create(AParent, Self)); FSections.Add(TOutParamsSection.Create(AParent, Self)); FSections.Add(TOutParamsNoStripSection.Create(AParent, Self)); FSections.Add(TIfHasComplexTypeSection.Create(AParent, Self)); FSections.Add(TIfOutParamsSection.Create(AParent, Self)); FSections.Add(TIfNoOutParamsSection.Create(AParent, Self)); FSections.Add(TIfResultComplexSection.Create(AParent, Self)); FSections.Add(TIfResultSimpleSection.Create(AParent, Self)); FSections.Add(TIfResultOtherTypeSection.Create(Parent, Self)); for DataType := Low(DataTypeNames) to High(DataTypeNames) do FSections.Add(TIfResultXXXTypeSection.Create(Parent, Self, DataTypeNames[DataType])); end; destructor TBaseOperationSection.Destroy; begin FSections.Free; inherited Destroy; end; procedure TBaseOperationSection.DoReplacements(var curLine: string; const aOperation: TRODLOperation; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); begin DoRODLEntityReplacements(curLine, aOperation, 'OPERATION'); // Next call will also call Parent.DoDefaultReplacements ParentSection.DoReplacements(curLine, aService, aLibrary); end; function TBaseOperationSection.GetParamsNoStripSectionClass: TParamsNoStripSectionClass; begin Result := TParamsNoStripSection; end; function TBaseOperationSection.InternalSectionStart(const line: string; var section: TBaseProcedureSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TBaseOperationSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); var curOpIndex: Integer; curOp: TRODLOperation; curLine: string; section: TBaseProcedureSubSection; begin for curOpIndex := 0 to aService.Default.Count - 1 do begin curOp := aService.Default.Items[curOpIndex]; if OperationApplies(curOp) then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, curOp, aService, aLibrary); if InternalSectionStart(curLine, section) then section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, curOp, aService) else Write(curLine); end; end; end; end; { TRequiredUnitsSection } constructor TRequiredUnitsSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'REQUIRED_UNITS'); end; procedure TRequiredUnitsSection.Process(const sectionText: string; const aLibrary: TRODLLibrary); var tmpStringList: TStringList; curLine: string; I: Integer; begin tmpStringList := TStringList.Create; try tmpStringList.Delimiter := ','; tmpStringList.DelimitedText := Parent.RequiredUnits; for I := 0 to tmpStringList.Count - 1 do begin curLine := sectionText; DoReplacements(curLine, tmpStringList[I], aLibrary); Write(curLine); end; finally tmpStringList.Free; end; end; procedure TRequiredUnitsSection.DoReplacements(var curLine: string; const unitName: string; const aLibrary: TRODLLibrary); begin Parent.DoDefaultReplacements(curLine, aLibrary); MacroReplace(curLine, '%', ['REQUIRED_UNIT_NAME', unitName ]); end; { TUsedRODLsSection } constructor TUsedRODLsSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'USED_RODLS'); end; procedure TUsedRODLsSection.Process(const sectionText: string; const aLibrary: TRODLLibrary); var i: Integer; unitName: string; curLine: string; begin for i := 0 to aLibrary.UseCount-1 do begin if aLibrary.Use[i].LoadedRodlLibraryName <> '' then unitName := aLibrary.Use[i].LoadedRodlLibraryName + '_Intf' else unitName := ChangeFileExt(ExtractFilename(aLibrary.Use[i].RodlFile),'')+'_Intf'; curLine := sectionText; DoReplacements(curLine, unitName, aLibrary); Write(curLine); end; end; procedure TUsedRODLsSection.DoReplacements(var curLine: string; unitName: string; const aLibrary: TRODLLibrary); begin Parent.DoDefaultReplacements(curLine, aLibrary); MacroReplace(curLine, '%', ['USED_RODL_UNIT_NAME', unitName ]); end; { TServicesSection } constructor TServicesSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'SERVICES'); FSections.Add(GetProcedureOperationsSectionClass.Create(AParent, Self)); FSections.Add(GetFunctionOperationsSectionClass.Create(AParent, Self)); end; procedure TServicesSection.DoReplacements(var curLine: string; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); var urn: string; begin inherited DoReplacements(curLine, aService, aLibrary); MacroReplace(curLine, '%', ['SERVICE_PROXY_ANCESTOR_NAME', GetProxyAncestorName(aService), 'SERVICE_INVOKER_ANCESTOR_NAME', GetInvokerAncestorName(aService) ]); // Write additional SOAP information if IsSOAPService(aService) then begin MacroReplace(curLine, '%', [GetEntityPrefix + '_LOCATION', aService.Info.Attributes.Values['Location'] ]); if (aService.Default.Count>0) then begin urn := aService.Default.Items[0].Info.Attributes.Values['Action']; if (urn='') then urn := aService.Default.Items[0].Info.Attributes.Values['InputNamespace']; // Apache ones... if (Pos('#', urn)>0) then Delete(urn, Pos('#', urn), Length(urn)); MacroReplace(curLine, '%', [GetEntityPrefix + '_URN', urn ]); end; end; end; function TServicesSection.GetEntityPrefix: string; begin Result := 'SERVICE'; end; function TServicesSection.GetFunctionOperationsSectionClass: TFunctionOperationsSectionClass; begin Result := TFunctionOperationsSection; end; function TServicesSection.GetInvokerAncestorName( const aService: TRODLBaseService): string; begin if Length(aService.Ancestor) = 0 then Result := DEFAULT_SERVICE_INVOKER_ANCESTOR_NAME else Result := aService.Ancestor + SERVICE_INVOKER_SUFFIX; end; function TServicesSection.GetProcedureOperationsSectionClass: TProcedureOperationsSectionClass; begin Result := TProcedureOperationsSection; end; function TServicesSection.GetProxyAncestorName( const aService: TRODLBaseService): string; begin if Length(aService.Ancestor) = 0 then Result := DEFAULT_SERVICE_PROXY_ANCESTOR_NAME else Result := aService.Ancestor + GetProxySuffix; end; function TServicesSection.GetProxySuffix: string; begin Result := SERVICE_PROXY_SUFFIX;; end; function TServicesSection.GetServiceList: IROStrings; begin Result := Parent.FOrderedServices; end; function TServicesSection.IsSOAPService(const aService: TRODLBaseService): Boolean; begin Result := aService.Attributes.Values['Type'] = 'SOAP'; end; { TEnumsSection } constructor TEnumsSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'ENUMS'); end; procedure TEnumsSection.DoReplacements(var curLine: string; aEnum: TRODLEnum; const aLibrary: TRODLLibrary); begin Parent.DoDefaultReplacements(curLine, aLibrary); DoRODLEntityReplacements(curLine, aEnum, 'ENUM'); end; class function TEnumsSection.GetEnumValueName(const enum: TRODLEnum; const ValueIndex: Integer): string; begin Result := enum[ValueIndex].Name; if enum.PrefixEnumValues then Result := enum.Name + '_' + Result; end; procedure TEnumsSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); var I: Integer; curEnum: TRODLEnum; curLine: string; begin for I := 0 to Parent.FOrderedEnums.Count - 1 do begin curEnum := Parent.FOrderedEnums.Objects[I] as TRODLEnum; if not curEnum.IsFromUsedRodl then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, curEnum, aLibrary); if SectionStart(curLine, 'VALUES') then ProcessValues(curEnum, FinishSection('VALUES', sectionTemplate)) else if SectionStart(curLine, 'DOCUMENTATION') then ProcessDocumentation(curEnum, FinishSection('DOCUMENTATION', sectionTemplate)) else Write(curLine); end; end; end; end; procedure TEnumsSection.ProcessValues(enum: TRODLEnum; const template: string); var I: Integer; curLine: string; begin for I := 0 to enum.Count - 1 do begin curLine := template; MacroReplace(curLine, '%', ['VALUE_NAME', GetEnumValueName(enum, I) ]); if I = enum.Count - 1 then begin curLine := StrEnsureNoSuffix(';', TrimRight(curLine)); curLine := StrEnsureNoSuffix(',', TrimRight(curLine)); end; Write(curLine); end; end; { TEventSinksSection } constructor TEventSinksSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'EVENT_SINKS'); FSections.Add(GetOperationsSectionClass.Create(AParent, Self)); end; procedure TEventSinksSection.DoReplacements(var curLine: string; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); var eventSink: TRODLEventSink; begin inherited DoReplacements(curLine, aService, aLibrary); eventSink := aService as TRODLEventSink; MacroReplace(curLine, '%', ['EVENT_SINK_WRITER_ANCESTOR_NAME', GetEventSinkWriterAncestorName(eventSink), 'EVENT_SINK_INVOKER_ANCESTOR_NAME', GetEventSinkInvokerAncestorName(eventSink) ]); end; function TEventSinksSection.GetEntityPrefix: string; begin Result := 'EVENT_SINK'; end; function TEventSinksSection.GetEventSinkInvokerAncestorName( const aEventSink: TRODLEventSink): string; begin Result := aEventSink.Ancestor; if Length(Result) = 0 then Result := DEFAULT_EVENT_SINK_INVOKER_ANCESTOR_NAME else Result := Result + EVENT_SINK_INVOKER_SUFFIX; end; function TEventSinksSection.GetEventSinkWriterAncestorName( const aEventSink: TRODLEventSink): string; begin Result := aEventSink.Ancestor; if Length(Result) = 0 then Result := DEFAULT_EVENT_SINK_WRITER_ANCESTOR_NAME else Result := Result + EVENT_SINK_WRITER_SUFFIX; end; function TEventSinksSection.GetOperationsSectionClass: TOperationsSectionClass; begin Result := TOperationsSection; end; function TEventSinksSection.GetServiceList: IROStrings; begin Result := Parent.FOrderedEventSinks; end; { TArraysSection } constructor TArraysSection.Create(AParent: TRODLTemplateBasedConverter); var DataType: TRODataType; begin inherited Create(AParent, 'ARRAYS'); FSections := TArraySubSectionList.Create(True); FSections.Add(TIfArrayTypeSimpleSection.Create(AParent, Self)); FSections.Add(TIfArrayTypeComplexSection.Create(AParent, Self)); FSections.Add(TIfArrayArrayTypeSection.Create(AParent, Self)); FSections.Add(TIfArrayEnumTypeSection.Create(AParent, Self)); FSections.Add(TIfArrayStructTypeSection.Create(AParent, Self)); for DataType := Low(TRODataType) to High(TRODataType) do FSections.Add(TIfArrayXXXTypeSection.Create(AParent, Self, DataTypeNames[DataType])); FSections.Add(TIfArrayXXXTypeSection.Create(AParent, Self, 'Utf8String')); end; destructor TArraysSection.Destroy; begin FSections.Free; inherited; end; procedure TArraysSection.DoReplacements(var curLine: string; const aArray: TRODLArray; const aLibrary: TRODLLibrary); begin Parent.DoDefaultReplacements(curLine, aLibrary); DoRODLEntityReplacements(curLine, aArray, 'ARRAY'); MacroReplace(curLine, '%', ['ARRAY_TYPE', Parent.GetTypeIdentifier(aArray.ElementType) ]); end; function TArraysSection.InternalSectionStart(const line: string; var section: TArraySubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TArraysSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary); var I: Integer; curArray: TRODLArray; curLine: string; section: TArraySubSection; begin for I := 0 to FParent.FOrderedArrays.Count - 1 do begin curArray := FParent.FOrderedArrays.Objects[I] as TRODLArray; if not curArray.IsFromUsedRodl then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, curArray, aLibrary); if InternalSectionStart(curLine, section) then begin section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, curArray) end else if SectionStart(curLine, 'DOCUMENTATION') then begin ProcessDocumentation(curArray, FinishSection('DOCUMENTATION', sectionTemplate)) end else begin Write(curLine); end; end; end; end; end; { TStructsSection } constructor TStructsSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'STRUCTS'); FSections.Add(TArraysIsFound.Create(AParent, Self)); end; function TStructsSection.GetAncestorName( const aStruct: TRODLBaseStruct): string; begin Result := aStruct.Ancestor; if Length(Result) = 0 then Result := DEFAULT_STRUCT_ANCESTOR; end; function TStructsSection.GetEntityPrefix: string; begin Result := 'STRUCT'; end; function TStructsSection.GetStructList: IROStrings; begin Result := Parent.FOrderedStructs; end; { TExceptionsSection } constructor TExceptionsSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'EXCEPTIONS'); // FSections.Add(TSerializerSection.Create(AParent, Self)); end; function TExceptionsSection.GetEntityPrefix: string; begin Result := 'EXCEPTION'; end; function TExceptionsSection.GetStructList: IROStrings; begin Result := Parent.FOrderedExceptions; end; function TExceptionsSection.GetAncestorName( const aStruct: TRODLBaseStruct): string; begin Result := aStruct.Ancestor; if Length(Result) = 0 then Result := DEFAULT_EXCEPTION_ANCESTOR; end; { TOperationsSection } constructor TOperationsSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); begin inherited Create(AParent, AParentSection, 'OPERATIONS'); end; function TOperationsSection.OperationApplies( aOperation: TRODLOperation): Boolean; begin Result := True; end; { TProcedureOperationsSection } constructor TProcedureOperationsSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); begin inherited Create(AParent, AParentSection, 'PROCEDURE_OPERATIONS'); end; function TProcedureOperationsSection.OperationApplies( aOperation: TRODLOperation): Boolean; begin Result := not Assigned(aOperation.Result) or (aOperation.Result.DataType = ''); end; { TFunctionOperationsSection } constructor TFunctionOperationsSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); begin inherited Create(AParent, AParentSection, 'FUNCTION_OPERATIONS'); end; procedure TFunctionOperationsSection.DoReplacements(var curLine: string; const aOperation: TRODLOperation; const aService: TRODLBaseService; const aLibrary: TRODLLibrary); begin inherited DoReplacements(curLine, aOperation, aService, aLibrary); GetParamsNoStripSectionClass.DoAttributeReplacements(curLine, aOperation.Result.DataType, 'OPERATION_RESULT'); MacroReplace(curLine, '%', ['OPERATION_RESULT', Parent.GetTypeIdentifier(aOperation.Result.DataType) ]); end; function TFunctionOperationsSection.OperationApplies( aOperation: TRODLOperation): Boolean; begin Result := Assigned(aOperation.Result) and (aOperation.Result.DataType <> ''); end; { TParamsSection } function TParamsSection.CanStrip: Boolean; begin Result := True; end; function TParamsSection.CanUse(const AParam: TRODLOperationParam): Boolean; begin Result := True; end; constructor TParamsSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); var DataType: TRODataType; begin inherited Create(AParent, AParentSection, 'PARAMS'); FSections := TParamSubSectionList.Create(True); FSections.Add(TIfParamTypeComplexSection.Create(Parent, Self)); FSections.Add(TIfParamTypeSimpleSection.Create(Parent, Self)); FSections.Add(TIfParamOtherTypeSection.Create(Parent, Self)); for DataType := Low(DataTypeNames) to High(DataTypeNames) do FSections.Add(TIfParamXXXTypeSection.Create(Parent, Self, DataTypeNames[DataType])); end; destructor TParamsSection.Destroy; begin FSections.Free; inherited Destroy; end; procedure TParamsSection.EnsureStripping(var curLine: string; IsLastParam: Boolean); begin if IsLastParam and CanStrip then begin curLine := StrEnsureNoSuffix(';', TrimRight(curLine)); curLine := StrEnsureNoSuffix(',', TrimRight(curLine)); end; end; class function TParamsSection.GetAttributeReplacement(const dataType: string): string; begin Result := ''; if LowerCase(dataType) = 'datetime' then Result := 'paIsDateTime'; end; class procedure TParamsSection.DoAttributeReplacements(var curLine: string; const dataType, prefix: string); var replacement: string; begin replacement := GetAttributeReplacement(dataType); MacroReplace(curLine, '%', [prefix + '_ATTRIBUTE', replacement ]) end; procedure TParamsSection.DoReplacements(var curLine: string; const aParameter: TRODLOperationParam; const aLibrary: TRODLLibrary); begin Parent.DoDefaultReplacements(curLine, aLibrary); DoRODLEntityReplacements(curLine, aParameter, 'PARAM'); DoAttributeReplacements(curLine, aParameter.DataType, 'PARAM'); MacroReplace(curLine, '%', ['PARAM_FRONT_MODIFIER', Parent.GetParamFrontModifier(aParameter.Flag), 'PARAM_BACK_MODIFIER', Parent.GetParamBackModifier(aParameter.Flag), 'PARAM_TYPE', Parent.GetTypeIdentifier(aParameter.DataType) ]); end; function TParamsSection.InternalSectionStart(const line: string; var section: TParamSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TParamsSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var I, J: Integer; curLine: string; curParam: TRODLOperationParam; section: TParamSubSection; IsLastParam: Boolean; begin for I := 0 to aOperation.Count - 1 do begin curParam := aOperation.Items[I]; if CanUse(curParam) then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, curParam, aLibrary); IsLastParam := (I = aOperation.Count-1); // it may happen that no parameters after the current one is usable, // hence making it effectively the last one. if not IsLastParam then begin J := I + 1; while (J < aOperation.Count) and not CanUse(aOperation.Items[J]) do Inc(J); IsLastParam := J = aOperation.Count; end; if InternalSectionStart(curLine, section) then begin section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, curParam, IsLastParam); end else begin EnsureStripping(curLine, sectionTemplate.Eof and IsLastParam); Write(curLine); end; end; end; end; end; { TParamsNoStripSection } function TParamsNoStripSection.CanStrip: Boolean; begin Result := False; end; constructor TParamsNoStripSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection); FName := 'PARAMS_NO_STRIP'; end; { TIfParamTypeComplexSection } constructor TIfParamTypeComplexSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection); begin inherited Create(AParent, AParentSection, 'IF_PARAM_TYPE_COMPLEX'); end; procedure TIfParamTypeComplexSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); begin if CachedIsImplementedAsClass(aParameter.DataType, aLibrary) then inherited Process(sectionText, aLibrary, aParameter, IsLastParam); end; { TIfParamTypeSimpleSection } constructor TIfParamTypeSimpleSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection); begin inherited Create(AParent, AParentSection, 'IF_PARAM_TYPE_SIMPLE'); end; procedure TIfParamTypeSimpleSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); begin if not CachedIsImplementedAsClass(aParameter.DataType, aLibrary) then inherited Process(sectionText, aLibrary, aParameter, IsLastParam); end; { TIfStructHasAncestor } constructor TIfStructHasAncestor.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); begin inherited Create(AParent, AParentSection, 'IF_STRUCT_HAS_ANCESTOR'); end; procedure TIfStructHasAncestor.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); begin if aStruct.Ancestor <> '' then inherited Process(sectionText, aLibrary, aStruct); end; { TFieldsSection } function TFieldsSection.CanStrip: Boolean; begin Result := True; end; constructor TFieldsSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); var DataType: TRODataType; begin inherited Create(AParent, AParentSection, 'FIELDS'); FSections := TFieldSubSectionList.Create(True); FSections.Add(TIfFieldTypeComplexSection.Create(AParent, Self)); FSections.Add(TIfFieldTypeSimpleSection.Create(AParent, Self)); FSections.Add(TIfStringFieldSection.Create(AParent, Self)); FSections.Add(TIfCurrencyFieldSection.Create(AParent, Self)); FSections.Add(TIfDecimalFieldSection.Create(AParent, Self)); FSections.Add(TIfVariantFieldSection.Create(AParent, Self)); FSections.Add(TIfFieldArrayTypeSection.Create(AParent, Self)); FSections.Add(TIfFieldEnumTypeSection.Create(AParent, Self)); FSections.Add(TIfFieldStructTypeSection.Create(AParent, Self)); for DataType := Low(DataType) to High(DataType) do FSections.Add(TIfFieldXXXTypeSection.Create(AParent, Self, DataTypeNames[DataType])); FSections.Add(TIfFieldXXXTypeSection.Create(AParent, Self, 'Utf8String')); end; destructor TFieldsSection.Destroy; begin FSections.Free; inherited Destroy; end; procedure TFieldsSection.ProcessField(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; AField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; IsLastField: Boolean); var section: TFieldSubSection; curLine: string; begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, AField, aStruct, aLibrary); if InternalSectionStart(curLine, section) then begin section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, AField, aStruct, IsLastField); end else begin EnsureStripping(curLine, sectionTemplate.Eof and IsLastField); Write(curLine); end; end; end; procedure TFieldsSection.DoReplacements(var curLine: string; curField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); begin DoRODLEntityReplacements(curLine, curField, 'FIELD'); MacroReplace(curLine, '%', ['FIELD_TYPE', Parent.GetTypeIdentifier(curField.DataType)]); ParentSection.DoReplacements(curLine, aStruct, aLibrary); end; procedure TFieldsSection.EnsureStripping(var curLine: string; IsLastField: Boolean); begin if IsLastField and CanStrip then begin curLine := StrEnsureNoSuffix(';', TrimRight(curLine)); curLine := StrEnsureNoSuffix(',', TrimRight(curLine)); end; end; function TFieldsSection.InternalSectionStart(const line: string; var section: TFieldSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TFieldsSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); var I: Integer; begin for I := 0 to aStruct.Count - 1 do begin ProcessField(sectionTemplate, aLibrary, aStruct.Items[I], aStruct, I = aStruct.Count - 1); end; end; { TFieldsNoStripSection } function TFieldsNoStripSection.CanStrip: Boolean; begin Result := False; end; constructor TFieldsNoStripSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); begin inherited Create(AParent, AParentSection); FName := 'FIELDS_NO_STRIP'; end; { TAncestorFieldsSection } function TAncestorFieldsSection.CanStrip: Boolean; begin Result := False; end; constructor TAncestorFieldsSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); begin inherited Create(AParent, AParentSection); FName := 'ANCESTOR_FIELDS'; end; procedure TAncestorFieldsSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); var I: Integer; ancestorStruct: TRODLBaseStruct; begin ancestorStruct := aLibrary.FindBaseStruct(aStruct.Ancestor); if Assigned(ancestorStruct) then begin for I := 0 to ancestorStruct.Count - 1 do begin ProcessField(sectionTemplate, aLibrary, ancestorStruct.Items[I], ancestorStruct, I = ancestorStruct.Count - 1); end; end; end; { TEntireHierarchyFieldsSection } function TEntireHierarchyFieldsSection.CanStrip: Boolean; begin Result := False; end; constructor TEntireHierarchyFieldsSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); begin inherited Create(AParent, AParentSection); FName := 'ENTIRE_HIERARCHY_FIELDS'; end; procedure TEntireHierarchyFieldsSection.ProcessTemplate( sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); var I: Integer; List: IROStrings; begin List := aStruct.CalcItemsMarshalingOrder(True); // remove duplicates I := 0; while I < List.Count - 1 do begin if List[I] = List[I + 1] then List.Delete(I) else Inc(I); end; // process for I := 0 to List.Count - 1 do ProcessField(sectionTemplate, aLibrary, TRODLTypedEntity(List.objects[i]), aStruct, I = List.Count - 1); List:=nil; end; { TIfFieldXXXTypeSection } function TIfFieldXXXTypeSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := SameText(aField.DataType, FDataType); end; constructor TIfFieldXXXTypeSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection; const DataType: string); begin FDataType := DataType; inherited Create(AParent, AParentSection, 'IF_FIELD_' + UpperCase(FDataType) + '_TYPE'); end; { TIfFieldArrayTypeSection } function TIfFieldArrayTypeSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := Parent.GlobalOrderedArrays.Find(aField.DataType) >= 0; end; constructor TIfFieldArrayTypeSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, 'IF_FIELD_ARRAY_TYPE'); end; { TIfFieldEnumTypeSection } function TIfFieldEnumTypeSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := Parent.GlobalOrderedEnums.Find(aField.DataType) >= 0; end; constructor TIfFieldEnumTypeSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, 'IF_FIELD_ENUM_TYPE'); end; { TIfFieldStructTypeSection } function TIfFieldStructTypeSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := Parent.GlobalOrderedStructs.Find(aField.DataType) >= 0; end; constructor TIfFieldStructTypeSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, 'IF_FIELD_STRUCT_TYPE'); end; { TIfFieldTypeComplexSection } constructor TIfFieldTypeComplexSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, 'IF_FIELD_TYPE_COMPLEX'); FSections := TFieldSubSectionList.Create(True); FSections.Add(TIfAutoCreateFieldsSection.Create(Parent, ParentSection)); FSections.Add(TIfNotAutoCreateFieldsSection.Create(Parent, ParentSection)); end; destructor TIfFieldTypeComplexSection.Destroy; begin FSections.Free; inherited Destroy; end; function TIfFieldTypeComplexSection.InternalSectionStart(const line: string; var section: TFieldSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TIfFieldTypeComplexSection.ProcessTemplate( sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct; const IsLastField: Boolean); var curLine: string; section: TFieldSubSection; begin if CachedIsImplementedAsClass(aField.DataType, aLibrary) then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; ParentSection.DoReplacements(curLine, aField, aStruct, aLibrary); ParentSection.EnsureStripping(curLine, IsLastField); if InternalSectionStart(curLine, section) then begin section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, aField, aStruct, IsLastField); end else begin Write(curLine); end; end; end; end; { TIfAutoCreateFieldsSection } function TIfAutoCreateFieldsSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := aStruct.AutoCreateParams; end; constructor TIfAutoCreateFieldsSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, 'IF_AUTO_CREATE_FIELDS'); end; { TIfNotAutoCreateFieldsSection } function TIfNotAutoCreateFieldsSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := not aStruct.AutoCreateParams; end; constructor TIfNotAutoCreateFieldsSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, 'IF_NOT_AUTO_CREATE_FIELDS'); end; { TIfFieldTypeSimpleSection } function TIfFieldTypeSimpleSection.CanUse(const aField: TRODLTypedEntity; const aStruct: TRODLBaseStruct): Boolean; begin Result := not CachedIsImplementedAsClass(aField.DataType, Parent.FLibrary); end; constructor TIfFieldTypeSimpleSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, 'IF_FIELD_TYPE_SIMPLE'); end; { TIfStringFieldSection } constructor TIfStringFieldSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, DataTypeNames[rtString]); FName := 'IF_STRING_FIELD'; end; { TIfCurrencyFieldSection } constructor TIfCurrencyFieldSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, DataTypeNames[rtCurrency]); FName := 'IF_CURRENCY_FIELD'; end; { TIfDecimalFieldSection } constructor TIfDecimalFieldSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, DataTypeNames[rtDecimal]); FName := 'IF_DECIMAL_FIELD'; end; { TIfVariantFieldSection } constructor TIfVariantFieldSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TFieldsSection); begin inherited Create(AParent, AParentSection, DataTypeNames[rtVariant]); FName := 'IF_VARIANT_FIELD'; end; { TIfHasFieldsSection } constructor TIfHasFieldsSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); begin inherited Create(AParent, AParentSection, 'IF_HAS_FIELDS'); FSections := TBaseStructSubSectionList.Create(True); FSections.Add(TIfStructHasAncestor.Create(AParent, AParentSection)); FSections.Add(TFieldsSection.Create(AParent, AParentSection)); FSections.Add(TFieldsNoStripSection.Create(AParent, AParentSection)); FSections.Add(TAncestorFieldsSection.Create(AParent, AParentSection)); FSections.Add(TEntireHierarchyFieldsSection.Create(AParent, AParentSection)); end; destructor TIfHasFieldsSection.Destroy; begin FSections.Free; inherited Destroy; end; procedure TIfHasFieldsSection.DoReplacements(var curLine: string; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); begin ParentSection.DoReplacements(curLine, aStruct, aLibrary); end; function TIfHasFieldsSection.InternalSectionStart(const line: string; var section: TBaseStructSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < FSections.Count) and not Result do begin if SectionStart(line, FSections[I].Name) then begin Result := True; section := FSections[I]; end; Inc(I); end; end; procedure TIfHasFieldsSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); var curLine: string; section: TBaseStructSubSection; begin if aStruct.Count > 0 then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, aStruct, aLibrary); if InternalSectionStart(curLine, section) then section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, aStruct) else Write(curLine); end; end; end; { TIfDataModuleSection } constructor TIfDataModuleSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'IF_DATA_MODULE'); end; procedure TIfDataModuleSection.Process(const sectionText: string; const aLibrary: TRODLLibrary); begin if Parent.WriteDataModule then inherited Process(sectionText, aLibrary); end; { TIfDataModuleServiceSection } constructor TIfDataModuleServiceSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); begin inherited Create(AParent, AParentSection, 'IF_DATA_MODULE'); end; procedure TIfDataModuleServiceSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); begin if Parent.WriteDataModule then ParentSection.Process(sectionText, aLibrary); end; { TIfHydraSection } constructor TIfHydraSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(AParent, 'IF_HYDRA'); FIsHydraModule := IsHydraModule; // put value in cache end; procedure TIfHydraSection.Process(const sectionText: string; const aLibrary: TRODLLibrary); begin if FIsHydraModule then inherited Process(sectionText, aLibrary); end; { TIfWSDLSection } constructor TIfWSDLSection.Create(AParent: TRODLTemplateBasedConverter); begin inherited Create(APArent, 'IF_WSDL'); end; procedure TIfWSDLSection.Process(const sectionText: string; const aLibrary: TRODLLibrary); var curLine: string; begin if aLibrary.Info.Attributes.Values['Wsdl'] <> '' then begin curLine := sectionText; MacroReplace(curLine, '%', ['WSDL_LOCATION', aLibrary.Info.Attributes.Values['Wsdl'] ]); end; Write(curLine); end; { TAncestorServicesSection } constructor TAncestorServicesSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TBaseServiceSection); begin inherited Create(AParent, AParentSection, 'ANCESTOR_SERVICES'); end; procedure TAncestorServicesSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aService: TRODLBaseService); var ancestors: TStringList; curService: TRODLBaseService; I: Integer; curLine: string; begin ancestors := TStringList.Create; try // build the ancestor's list curService := aService; while Assigned(curService) and (Length(curService.Ancestor) > 0) do begin ancestors.Add(curService.Ancestor); curService := aLibrary.FindService(curService.Ancestor); end; // process it for I := 0 to ancestors.Count - 1 do begin curLine := sectionText; MacroReplace(curLine, '%', ['ANCESTOR_SERVICE_NAME', ancestors[I] ]); inherited Process(curLine, aLibrary, aService); end; finally ancestors.Free; end; end; { TIfHasComplexTypeSection } constructor TIfHasComplexTypeSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection, 'IF_HAS_COMPLEX_TYPE'); FSections := TBaseProcedureSubSectionList.Create(True); FSections.Add(TIfResultComplexSection.Create(AParent, AParentSection)); FSections.Add(TIfResultSimpleSection.Create(AParent, AParentSection)); FSections.Add(TParamsNoStripSection.Create(AParent, AParentSection)); FSections.Add(TOutParamsNoStripSection.Create(AParent, AParentSection)); end; destructor TIfHasComplexTypeSection.Destroy; begin FSections.Free; inherited Destroy; end; function TIfHasComplexTypeSection.InternalSectionStart(const line: string; var section: TBaseProcedureSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; function TIfHasComplexTypeSection.OperationHasComplexType( const aOperation: TRODLOperation; const aLibrary: TRODLLibrary): Boolean; var I: Integer; begin Result := (Assigned(aOperation.Result) and CachedIsImplementedAsClass(aOperation.Result.DataType, aLibrary)); I := 0; while not Result and (I < aOperation.Count) do begin Result := CachedIsImplementedAsClass(aOperation.Items[I].DataType, aLibrary); Inc(I); end; end; procedure TIfHasComplexTypeSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var curLine: string; section: TBaseProcedureSubSection; begin if OperationHasComplexType(aOperation, aLibrary) then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; if InternalSectionStart(curLine, section) then section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, aOperation, aService) else Write(curLine); end; end; end; { TIfArrayTypeSimple } function TIfArrayTypeSimpleSection.CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; begin Result := not CachedIsImplementedAsClass(aArray.ElementType, aLibrary); end; constructor TIfArrayTypeSimpleSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TArraysSection); begin inherited Create(AParent, AParentSection, 'IF_ARRAY_TYPE_SIMPLE'); end; { TIfArrayTypeComplex } function TIfArrayTypeComplexSection.CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; begin Result := CachedIsImplementedAsClass(aArray.ElementType, aLibrary); end; constructor TIfArrayTypeComplexSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TArraysSection); begin inherited Create(AParent, AParentSection, 'IF_ARRAY_TYPE_COMPLEX'); end; { TIfArrayXXXTypeSection } function TIfArrayXXXTypeSection.CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; begin Result := SameText(aArray.ElementType, FDataType); end; constructor TIfArrayXXXTypeSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection; const DataType: string); begin FDataType := DataType; inherited Create(AParent, AParentSection, 'IF_ARRAY_' + UpperCase(DataType) + '_TYPE'); end; { TIfArrayArrayTypeSection } function TIfArrayArrayTypeSection.CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; begin Result := Parent.GlobalOrderedArrays.Find(aArray.ElementType) >= 0; end; constructor TIfArrayArrayTypeSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection); begin inherited Create(AParent, AParentSection, 'IF_ARRAY_ARRAY_TYPE'); end; { TIfArrayEnumTypeSection } function TIfArrayEnumTypeSection.CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; begin Result := Parent.GlobalOrderedEnums.Find(aArray.ElementType) >= 0; end; constructor TIfArrayEnumTypeSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection); begin inherited Create(AParent, AParentSection, 'IF_ARRAY_ENUM_TYPE'); end; { TIfArrayStructTypeSection } function TIfArrayStructTypeSection.CanUse(const aArray: TRODLArray; const aLibrary: TRODLLibrary): Boolean; begin Result := Parent.GlobalOrderedStructs.Find(aArray.ElementType) >= 0; end; constructor TIfArrayStructTypeSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TArraysSection); begin inherited Create(AParent, AParentSection, 'IF_ARRAY_STRUCT_TYPE'); end; { TInParamsSection } function TInParamsSection.CanUse(const AParam: TRODLOperationParam): Boolean; begin Result := AParam.Flag in IN_FLAGS; end; constructor TInParamsSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection); FName := 'IN_PARAMS'; end; { TInParamsNoStripSection } function TInParamsNoStripSection.CanStrip: Boolean; begin Result := False; end; constructor TInParamsNoStripSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection); FName := 'IN_PARAMS_NO_STRIP'; end; { TOutParamsSection } function TOutParamsSection.CanUse(const AParam: TRODLOperationParam): Boolean; begin Result := AParam.Flag in OUT_FLAGS; end; constructor TOutParamsSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection); FName := 'OUT_PARAMS'; end; { TOutParamsNoStripSection } function TOutParamsNoStripSection.CanStrip: Boolean; begin Result := False; end; constructor TOutParamsNoStripSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection); FName := 'OUT_PARAMS_NO_STRIP'; end; { TIfOutParamsSection } function TIfOutParamsSection.CanUse(const aOperation: TRODLOperation): Boolean; var I: Integer; begin Result := False; I := 0; while not Result and (I < aOperation.Count) do begin if aOperation.Items[I].Flag in OUT_FLAGS then Result := True; Inc(I); end; end; constructor TIfOutParamsSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection, 'IF_OUT_PARAMS'); FSections := TBaseProcedureSubSectionList.Create(True); FSections.Add(TOutParamsSection.Create(AParent, AParentSection)); FSections.Add(TOutParamsNoStripSection.Create(AParent, AParentSection)); end; destructor TIfOutParamsSection.Destroy; begin FSections.Free; inherited Destroy; end; function TIfOutParamsSection.InternalSectionStart(const line: string; var section: TBaseProcedureSubSection): Boolean; var I: Integer; begin I := 0; Result := False; while (I < Sections.Count) and not Result do begin if SectionStart(line, Sections[I].Name) then begin Result := True; section := Sections[I]; end; Inc(I); end; end; procedure TIfOutParamsSection.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var curLine: string; section: TBaseProcedureSubSection; begin if CanUse(aOperation) then begin sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; ParentSection.DoReplacements(curLine, aOperation, aService, aLibrary); if InternalSectionStart(curLine, section) then section.Process(FinishSection(section.Name, sectionTemplate), aLibrary, aOperation, aService) else Write(curLine); end; end; end; { TIfNoOutParamsSection } constructor TIfNoOutParamsSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection); FName := 'IF_NO_OUT_PARAMS'; end; function TIfNoOutParamsSection.CanUse(const aOperation: TRODLOperation): Boolean; begin Result := not inherited CanUse(aOperation); end; { TResultSection } constructor TIfResultComplexSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection, 'IF_RESULT_COMPLEX'); end; procedure TIfResultComplexSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var curLine: string; begin if Assigned(aOperation.Result) and CachedIsImplementedAsClass(aOperation.Result.DataType, aLibrary) then begin curLine := sectionText; ParentSection.DoReplacements(curLine, aOperation, aService, aLibrary); Write(curLine); end; end; { TIfResultSimpleSection } constructor TIfResultSimpleSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection, 'IF_RESULT_SIMPLE'); end; procedure TIfResultSimpleSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var curLine: string; begin if not Assigned(aOperation.Result) or not CachedIsImplementedAsClass(aOperation.Result.DataType, aLibrary) then begin curLine := sectionText; ParentSection.DoReplacements(curLine, aOperation, aService, aLibrary); Write(curLine); end; end; { TArraysIsFound } constructor TArraysIsFound.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseStructSection); begin inherited Create(AParent, AParentSection, 'ARRAYS_IS_FOUND'); end; procedure TArraysIsFound.DoReplacements(var curLine: string; const aArray: TRODLArray; const aStruct: TRODLBaseStruct; const aLibrary: TRODLLibrary); begin MacroReplace(curLine, '%', ['ARRAY_NAME', aArray.Name ]); ParentSection.DoReplacements(curLine, aStruct, aLibrary); end; procedure TArraysIsFound.ProcessTemplate(sectionTemplate: TLineStream; const aLibrary: TRODLLibrary; const aStruct: TRODLBaseStruct); var curIndex: Integer; curAr: TRODLArray; curLine: string; aList: TList; begin aList := TList.Create; try aLibrary.GetArraysByElement(AStruct.Name,aList); for curIndex := 0 to aList.Count - 1 do begin curAr := TRODLArray(AList[curIndex]); sectionTemplate.Position := 0; while not sectionTemplate.Eof do begin curLine := sectionTemplate.ReadLine; DoReplacements(curLine, curAr, aStruct, aLibrary); Write(curLine); end; end; finally aList.Free; end; end; { TIfParamTypeSection } constructor TIfParamXXXTypeSection.Create(AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection; const DataType: string); begin FDataType := DataType; inherited Create(AParent, AParentSection, 'IF_PARAM_' + UpperCase(FDataType) + '_TYPE'); end; procedure TIfParamXXXTypeSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); begin if SameText(aParameter.DataType, FDataType) then inherited Process(sectionText, aLibrary, aParameter, IsLastParam); end; { TIfParamOtherTypeSection } constructor TIfParamOtherTypeSection.Create( AParent: TRODLTemplateBasedConverter; const AParentSection: TParamsSection); begin inherited Create(AParent, AParentSection, 'IF_PARAM_OTHER_TYPE'); end; procedure TIfParamOtherTypeSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aParameter: TRODLOperationParam; const IsLastParam: Boolean); var DataType: TRODataType; Found: Boolean; begin Found := False; DataType := Low(DataTypeNames); while not Found and (DataType <> High(DataTypeNames)) do begin Found := SameText(DataTypeNames[DataType], aParameter.DataType); DataType := Succ(DataType); end; if not Found then inherited Process(sectionText, aLibrary, aParameter, IsLastParam); end; { TIfResultXXXTypeSection } constructor TIfResultXXXTypeSection.Create(AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection; const DataType: string); begin FDataType := DataType; inherited Create(AParent, AParentSection, 'IF_RESULT_' + UpperCase(FDataType) + '_TYPE'); end; procedure TIfResultXXXTypeSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var curLine: string; begin if Assigned(aOperation.Result) and SameText(aOperation.Result.DataType, FDataType) then begin curLine := sectionText; ParentSection.DoReplacements(curLine, aOperation, aService, aLibrary); inherited Process(curLine, aLibrary, aOperation, aService); end; end; { TIfResultOtherTypeSection } constructor TIfResultOtherTypeSection.Create( AParent: TRODLTemplateBasedConverter; AParentSection: TBaseOperationSection); begin inherited Create(AParent, AParentSection, 'IF_RESULT_OTHER_TYPE'); end; procedure TIfResultOtherTypeSection.Process(const sectionText: string; const aLibrary: TRODLLibrary; const aOperation: TRODLOperation; const aService: TRODLBaseService); var DataType: TRODataType; Found: Boolean; curLine: string; begin if Assigned(aOperation.Result) then begin Found := False; DataType := Low(DataTypeNames); while not Found and (DataType <> High(DataTypeNames)) do begin Found := SameText(DataTypeNames[DataType], aOperation.Result.DataType); DataType := Succ(DataType); end; if not Found then begin curLine := sectionText; ParentSection.DoReplacements(curLine, aOperation, aService, aLibrary); inherited Process(curLine, aLibrary, aOperation, aService); end; end; end; end.