unit uRODLToXML; {----------------------------------------------------------------------------} { RemObjects SDK Library - CodeGen } { } { compiler: Delphi 5 and up, Kylix 2 and up } { platform: Win32, Linux } { } { (c)opyright RemObjects Software. all rights reserved. } { } { Using this code requires a valid license of the RemObjects SDK } { which can be obtained at http://www.remobjects.com. } {----------------------------------------------------------------------------} {$IFNDEF MSWINDOWS} {$I ../RemObjects.inc} {$ELSE} {$I ..\RemObjects.inc} {$ENDIF} interface uses SysUtils, Classes,uRODL; var XMLFlagNames: XMLFlagNamesArray deprecated; type { TRODLToXML } TRODLToXML = class(TRODLConverter) private fFlattenUsedRODLs:boolean; fStyleSheet: string; procedure WriteArrays(xml: TStringList; aLibrary: TRODLLibrary); procedure WriteAttributes(xml: TStringList; aEntity: TRODLEntity); procedure WriteEnums(xml: TStringList; aLibrary: TRODLLibrary); procedure WriteEventSinks(xml: TStringList; aLibrary: TRODLLibrary); procedure WriteExceptions(xml: TStringList; aLibrary: TRODLLibrary); procedure WriteServices(xml: TStringList; aLibrary: TRODLLibrary); procedure WriteStructs(xml: TStringList; aLibrary: TRODLLibrary); procedure WriteUses(xml: TStringList; aLibrary: TRODLLibrary); function WriteAsCData(aData: string): string; function Indent(SpaceCount: byte): string; protected procedure IntConvert(const aLibrary: TRODLLibrary; const aTargetEntity: string = ''); override; public constructor Create(const aLibrary: TRODLLibrary; iFlattenUsedRODLs:boolean=false); reintroduce; overload; constructor Create(const aLibraryFile: string; iFlattenUsedRODLs:boolean=false); reintroduce; overload; property StyleSheet: string read fStyleSheet write fStyleSheet; end; TXMLToRODL = uRODL.TXMLToRODL; function XMLFlagNameToFlag(const aName: string): TRODLParamFlag; function LoadLibraryFromXml(const aFilename: string): TRODLLibrary; implementation uses {$IFDEF DEBUG_REMOBJECTS_RODLTOXML}eDebugServer, {$ENDIF} TypInfo, {$IFDEF DELPHI5}ComObj,{$ENDIF} uRORes, uROXMLIntf; function XMLFlagNameToFlag(const aName: string): TRODLParamFlag; begin result := uRODL.XMLFlagNameToFlag(aName); end; function LoadLibraryFromXml(const aFilename: string): TRODLLibrary; begin with uRODL.TXMLToRODL.Create do try result := ReadFromFile(aFilename); finally Free; end; end; constructor TRODLToXML.Create(const aLibrary: TRODLLibrary; iFlattenUsedRODLs: boolean); begin fFlattenUsedRODLs := iFlattenUsedRODLs; inherited Create(aLibrary); end; constructor TRODLToXML.Create(const aLibraryFile: string; iFlattenUsedRODLs: boolean); begin fFlattenUsedRODLs := iFlattenUsedRODLs; inherited Create(aLibraryFIle); end; procedure TRODLToXML.IntConvert(const aLibrary: TRODLLibrary; const aTargetEntity: string = ''); var lAdditional: string; xml: TStringList; begin xml := TStringList.Create; with aLibrary do try {$IFDEF FPC} if aTargetEntity = '' then lAdditional := '' else //remove FPC warning {$ENDIF FPC} lAdditional := ''; if Namespace <> '' then lAdditional := 'Namespace="' + Namespace + '" '; xml.Append(''); if fStyleSheet <> '' then xml.Append(''); xml.Append(Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, aLibrary); WriteServices(xml, aLibrary); WriteEventSinks(xml, aLibrary); WriteStructs(xml, aLibrary); WriteEnums(xml, aLibrary); WriteArrays(xml, aLibrary); WriteUses(xml, aLibrary); WriteExceptions(xml, aLibrary); xml.Append(''); finally Buffer.AddStrings(xml); xml.Free; end; end; procedure TRODLToXML.WriteArrays(xml: TStringList; aLibrary: TRODLLibrary); var i: Integer; begin xml.Append(Indent(3) + ''); with aLibrary do for i := 0 to (ArrayCount - 1) do begin if fFlattenUsedRODLs or not Arrays[i].IsFromUsedRodl then with Arrays[i] do begin xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(3) + Format('', [ElementType])); xml.Append(Indent(6) + ''); end; end; xml.Append(Indent(3) + ''); end; function TRODLToXML.WriteAsCData(aData: string): string; function CleanCDATA(const aString: string): string; var lLength: Integer; begin result := aString; lLength := length(aString); while (lLength > 0) and {$IFDEF UNICODE} (CharInSet(result[lLength],[#09,#10,#13,#32])) {$ELSE} (result[lLength] in [#09,#10,#13,#32]) {$ENDIF} do dec(lLength); SetLength(result, lLength); for lLength := Length(Result) downto 1 do if {$IFDEF UNICODE} CharInSet(Result[lLength] , [#0..#8,#11,#12,#14..#31]) {$ELSE} (Result[lLength] in [#0..#8,#11,#12,#14..#31]) {$ENDIF} then result[lLength] := #32; result := StringReplace(result, ']]>', ']]>', [rfReplaceAll]); end; begin result := ''{$IFDEF UNICODE})){$ENDIF}; end; function SafeHtmlAttribute(const s: string): string; begin result := StringReplace(s, '&', '&' , [rfReplaceAll]); end; procedure TRODLToXML.WriteAttributes(xml: TStringList; aEntity: TRODLEntity); var attr: Integer; begin if aEntity.Documentation <> '' then xml.Append(Indent(6) + '' + WriteAsCData(aEntity.Documentation) + ''); if (aEntity.Attributes.Count > 0) then begin with aEntity.Attributes do begin xml.Append(Indent(6) + ''); for attr := 0 to (aEntity.Attributes.Count - 1) do xml.Append(Indent(9) + Format('<%s Value="%s" />', [Names[attr], SafeHtmlAttribute(Values[Names[attr]])])); xml.Append(Indent(6) + ''); end; end; if Assigned(aEntity.GroupUnder) then xml.Append(Indent(6) + Format('', [GUIDToString(aEntity.GroupUnder.UID)])); end; procedure TRODLToXML.WriteEnums(xml: TStringList; aLibrary: TRODLLibrary); var i, k: Integer; begin xml.Append(Indent(3) + ''); with aLibrary do for i := 0 to (EnumCount - 1) do begin if fFlattenUsedRODLs or not Enums[i].IsFromUsedRodl then with Enums[i] do begin if not PrefixEnumValues then xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID)])) else xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(3) + ''); for k := 0 to (Count - 1) do begin with Items[k] do begin xml.Append(Indent(9) + Format('', [Name])); WriteAttributes(xml, Info); xml.Append(Indent(9) + ''); end; end; xml.Append(Indent(3) + ''); xml.Append(Indent(6) + ''); end; end; xml.Append(Indent(3) + ''); end; procedure TRODLToXML.WriteEventSinks(xml: TStringList; aLibrary: TRODLLibrary); var i, k, m, p: Integer; lAdditional: string; begin with aLibrary do if EventSinkCount > 0 then begin xml.Append(Indent(3) + ''); for i := 0 to (EventSinkCount - 1) do begin if fFlattenUsedRODLs or not EventSinks[i].IsFromUsedRodl then with EventSinks[i] do begin lAdditional := ''; if ImplUnit <> '' then lAdditional := ' ImplUnit="' + ImplUnit + '"'; if ImplClass <> '' then lAdditional := lAdditional + ' ImplClass="' + ImplClass + '"'; if Ancestor <> '' then lAdditional := lAdditional + ' Ancestor="' + Ancestor + '"'; if Abstract then lAdditional := lAdditional + ' Abstract="1"'; xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(6) + ''); for k := 0 to (Count - 1) do begin with Items[k] do begin xml.Append(Indent(9) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(6) + ''); for m := 0 to (Count - 1) do begin with Items[m] do begin xml.Append(Indent(9) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(6) + ''); { ToDo: cloned from above for now; implement "proper" RODL->XML for 3.0 } if Assigned(Result) then with Result do begin with Result do begin xml.Append(Format('', [Name, DataType, uRODL.XMLFlagNames[Flag]])); WriteAttributes(xml, Info); xml.Append(''); end; end; for p := 0 to (Count - 1) do begin with Items[p] do begin xml.Append(Format('', [Name, DataType, uRODL.XMLFlagNames[Flag]])); WriteAttributes(xml, Info); xml.Append(''); end; end; xml.Append(Indent(6) + ''); xml.Append(Indent(9) + ''); end; end; xml.Append(Indent(6) + ''); xml.Append(Indent(9) + ''); end; end; xml.Append(Indent(6) + ''); xml.Append(Indent(6) + ''); end; end; xml.Append(Indent(3) + ''); end; end; procedure TRODLToXML.WriteExceptions(xml: TStringList; aLibrary: TRODLLibrary); var i, k: Integer; lAdd: string; begin with aLibrary do if ExceptionCount > 0 then begin xml.Append(Indent(3) + ''); for i := 0 to (ExceptionCount - 1) do begin if fFlattenUsedRODLs or not Exceptions[i].IsFromUsedRodl then with Exceptions[i] do begin lAdd := ''; if AutoCreateParams then lAdd := ' AutoCreateParams="1"' else lAdd := ' AutoCreateParams="0"'; if Ancestor <> '' then lAdd := lAdd+Format(' Ancestor="%s"',[Ancestor]); if Abstract then lAdd := lAdd + ' Abstract="1"'; xml.Append(Indent(6) + Format('',[Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(3) + ''); for k := 0 to (Count - 1) do begin with Items[k] do begin xml.Append(Indent(9) + Format('', [Name, DataType])); WriteAttributes(xml, Info); xml.Append(Indent(9) + Format('', [Name, DataType])); end; end; xml.Append(Indent(3) + ''); xml.Append(Indent(6) + '') end; end; xml.Append(Indent(3) + ''); end; end; procedure TRODLToXML.WriteServices(xml: TStringList; aLibrary: TRODLLibrary); var i, k, m, p: Integer; lAdditional: string; begin with aLibrary do begin if GroupCount > 0 then begin xml.Append(Indent(3) + ''); for i := 0 to (GroupCount - 1) do begin if fFlattenUsedRODLs or not Groups[i].IsFromUsedRodl then begin with Groups[i] do begin xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(6) + ''); end; end; end; xml.Append(Indent(3) + ''); end; xml.Append(Indent(3) + ''); for i := 0 to (ServiceCount - 1) do begin if fFlattenUsedRODLs or not Services[i].IsFromUsedRodl then with Services[i] do begin lAdditional := ''; if ImplUnit <> '' then lAdditional := ' ImplUnit="' + ImplUnit + '"'; if ImplClass <> '' then lAdditional := lAdditional + ' ImplClass="' + ImplClass + '"'; if Ancestor <> '' then lAdditional := lAdditional + ' Ancestor="' + Ancestor + '"'; if Abstract then lAdditional := lAdditional + ' Abstract="1"'; if isPrivate then lAdditional := lAdditional + ' Private="1"'; xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(6) + ''); for k := 0 to (Count - 1) do begin with Items[k] do begin xml.Append(Indent(9) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(6) + ''); for m := 0 to (Count - 1) do begin with Items[m] do begin if ForceAsyncResponse then xml.Append(Indent(9) + Format('', [Name, GUIDToString(UID)])) else xml.Append(Indent(9) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(6) + ''); if Assigned(Result) then with Result do begin with Result do begin xml.Append(Format('', [Name, DataType, uRODL.XMLFlagNames[Flag]])); WriteAttributes(xml, Info); xml.Append(''); end; end; for p := 0 to (Count - 1) do begin with Items[p] do begin xml.Append(Format('', [Name, DataType, uRODL.XMLFlagNames[Flag]])); WriteAttributes(xml, Info); xml.Append(''); end; end; xml.Append(Indent(6) + ''); if CodeBodyCount > 0 then begin xml.Append(Indent(6) + ''); for p := 0 to CodeBodyCount-1 do begin xml.Append(Indent(6) + '' + WriteAsCData(CodeBodies[CodeBodyLanguages[p]].Text) + ''); end; xml.Append(Indent(6) + ''); end; xml.Append(Indent(9) + ''); end; end; xml.Append(Indent(6) + ''); xml.Append(Indent(9) + ''); end; end; xml.Append(Indent(6) + ''); xml.Append(Indent(6) + ''); end; end; end; xml.Append(Indent(3) + ''); end; procedure TRODLToXML.WriteStructs(xml: TStringList; aLibrary: TRODLLibrary); var i, k: Integer; lAdditional: string; begin xml.Append(Indent(3) + ''); with aLibrary do for i := 0 to (StructCount - 1) do begin if fFlattenUsedRODLs or not Structs[i].IsFromUsedRodl then with Structs[i] do begin lAdditional := ''; if AutoCreateParams then lAdditional := ' AutoCreateParams="1"' else lAdditional := ' AutoCreateParams="0"'; if Ancestor <> '' then lAdditional := lAdditional + Format(' Ancestor="%s"', [Ancestor]); if Abstract then lAdditional := lAdditional + ' Abstract="1"'; xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID)])); WriteAttributes(xml, Info); xml.Append(Indent(3) + ''); for k := 0 to (Count - 1) do begin with Items[k] do begin xml.Append(Indent(9) + Format('', [Name, DataType])); WriteAttributes(xml, Info); xml.Append(Indent(9) + Format('', [Name, DataType])); end; end; xml.Append(Indent(3) + ''); xml.Append(Indent(6) + ''); end; end; xml.Append(Indent(3) + ''); end; procedure TRODLToXML.WriteUses(xml: TStringList; aLibrary: TRODLLibrary); var i: Integer; lSplitModeAttribute: string; lUsedRodlFilename, lUsedRodlFilename_absolute: string; begin with aLibrary do if UseCount > 0 then begin xml.Append(Indent(3) + ''); for i := 0 to (UseCount - 1) do begin if (not fFlattenUsedRODLs) and (not Use[i].IsFromUsedRodl) then with Use[i] do begin lUsedRodlFilename := RodlFile; lUsedRodlFilename_absolute := AbsoluteRodlFile; if lUsedRodlFilename_absolute = '' then lUsedRodlFilename_absolute := ExpandFileName(ExpandVariables(lUsedRodlFilename)); {if aLibrary.RodlFilename <> '' then lUsedRodlFilename := ExtractRelativePath(ExtractFilePath(aLibrary.RodlFilename),lUsedRodlFilename);} lSplitModeAttribute := ''; if SplitMode <> usmAsParent then lSplitModeAttribute := Format(' SplitMode="%s"', [IntToStr(Integer(SplitMode))]); if GenerateCode then xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID), lUsedRodlFilename, lUsedRodlFilename_absolute, lSplitModeAttribute])) else xml.Append(Indent(6) + Format('', [Name, GUIDToString(UID), lUsedRodlFilename, lUsedRodlFilename_absolute, lSplitModeAttribute])); WriteAttributes(xml, Info); xml.Append(Indent(6) + '') end; end; xml.Append(Indent(3) + ''); end; end; function TRODLToXML.Indent(SpaceCount: byte): string; {var i: integer;} begin {$IFDEF FPC} if SpaceCount = 0 then result := '' else // removing FPC warning {$ENDIF} result := ''; {for i := 1 to SpaceCount do result := result + ' ';} end; (* function StringToGUID(const s: string): TGUID; begin if s = '' then Result := NewGuid else begin try Result := Sysutils.StringToGUID(s); except on e: EConvertError do Result := NewGuid; end; end; end; *) initialization {$WARN SYMBOL_DEPRECATED OFF} XMLFlagNames := uRODL.XMLFlagNames; {$WARN SYMBOL_DEPRECATED ON} end.