From 1e1226949033386b3b990aeba54a835c41dfdac2 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Fri, 21 Jun 2013 11:05:00 +0000 Subject: [PATCH] Enumerator support for node collections --- Shared/XMLDataBindingUtils.pas | 42 ++++++++++++++ Units/DelphiXMLDataBindingGenerator.pas | 73 +++++++++++++++++++++++-- Units/DelphiXMLDataBindingResources.pas | 25 +++++++++ 3 files changed, 136 insertions(+), 4 deletions(-) diff --git a/Shared/XMLDataBindingUtils.pas b/Shared/XMLDataBindingUtils.pas index cd7f043..2b0d80d 100644 --- a/Shared/XMLDataBindingUtils.pas +++ b/Shared/XMLDataBindingUtils.pas @@ -46,6 +46,21 @@ type end; + TXMLNodeCollectionEnumerator = class(TInterfacedObject) + private + FNodeCollection: IXMLNodeCollection; + FIndex: Integer; + public + constructor Create(ANodeCollection: IXMLNodeCollection); + + function GetCurrent: IXMLNode; + function MoveNext: Boolean; virtual; + + property Current: IXMLNode read GetCurrent; + end; + + + const AllTimeFragments = [Low(TXMLTimeFragment)..High(TXMLTimeFragment)]; @@ -160,6 +175,33 @@ end; +{ TXMLNodeCollectionEnumerator } +constructor TXMLNodeCollectionEnumerator.Create(ANodeCollection: IXMLNodeCollection); +begin + inherited Create; + + FNodeCollection := ANodeCollection; + FIndex := -1; +end; + + +function TXMLNodeCollectionEnumerator.GetCurrent: IXMLNode; +begin + if (FIndex >= 0) and (FIndex < FNodeCollection.Count) then + Result := FNodeCollection.Nodes[FIndex] + else + Result := nil; +end; + + +function TXMLNodeCollectionEnumerator.MoveNext: Boolean; +begin + Inc(FIndex); + Result := (FIndex < FNodeCollection.Count); +end; + + + function DateTimeToXML(ADate: TDateTime; AFormat: TXMLDateTimeFormat; ATimeFragments: TXMLTimeFragments): string; var formatSettings: TFormatSettings; diff --git a/Units/DelphiXMLDataBindingGenerator.pas b/Units/DelphiXMLDataBindingGenerator.pas index 7dd4785..6159f65 100644 --- a/Units/DelphiXMLDataBindingGenerator.pas +++ b/Units/DelphiXMLDataBindingGenerator.pas @@ -69,6 +69,8 @@ type procedure WriteSchemaEnumerationArray(AStream: TStreamHelper; AItem: TXMLDataBindingEnumeration); procedure WriteValidate(AStream: TStreamHelper; AItem: TXMLDataBindingInterface; ASection: TDelphiXMLSection); + procedure WriteEnumeratorMethod(AStream: TStreamHelper; AItem: TXMLDataBindingInterface; ASection: TDelphiXMLSection); + procedure WriteEnumerator(AStream: TStreamHelper; AItem: TXMLDataBindingInterface; ASection: TDelphiXMLSection); function GetDelphiNodeType(AProperty: TXMLDataBindingProperty): TDelphiNodeType; function GetDelphiElementType(AProperty: TXMLDataBindingProperty): TDelphiElementType; @@ -695,8 +697,10 @@ begin if Assigned(AItem.BaseItem) then parent := PrefixInterface + AItem.BaseItem.TranslatedName else if AItem.IsCollection then - parent := CollectionInterface - else + begin + parent := CollectionInterface; + WriteEnumerator(AStream, AItem, ASection); + end else parent := ItemInterface; @@ -717,8 +721,10 @@ begin if Assigned(AItem.BaseItem) then parent := PrefixClass + AItem.BaseItem.TranslatedName else if AItem.IsCollection then - parent := CollectionClass - else + begin + parent := CollectionClass; + WriteEnumerator(AStream, AItem, ASection); + end else parent := ItemClass; @@ -738,6 +744,7 @@ begin dxsImplementation: begin + WriteEnumerator(AStream, AItem, ASection); WriteSchemaInterfaceProperties(AStream, AItem, ASection); end; end; @@ -937,6 +944,7 @@ begin AStream.WriteLn(' protected'); WriteValidate(AStream, AItem, ASection); + WriteEnumeratorMethod(AStream, AItem, ASection); hasMembers := WriteSchemaInterfaceCollectionProperties(AStream, AItem, ASection); for member := Low(TDelphiXMLMember) to High(TDelphiXMLMember) do @@ -1594,6 +1602,63 @@ begin end; +procedure TDelphiXMLDataBindingGenerator.WriteEnumeratorMethod(AStream: TStreamHelper; AItem: TXMLDataBindingInterface; ASection: TDelphiXMLSection); +begin + if not AItem.IsCollection then + Exit; + + case ASection of + dxsInterface, + dxsClass: + begin + AStream.WriteLnNamedFmt(EnumeratorMethodInterface, + ['Name', AItem.TranslatedName]); + AStream.WriteLn(''); + end; + + dxsImplementation: + begin + AStream.WriteLnNamedFmt(EnumeratorMethodImplementation, + ['Name', AItem.TranslatedName]); + end; + end; +end; + + + +procedure TDelphiXMLDataBindingGenerator.WriteEnumerator(AStream: TStreamHelper; AItem: TXMLDataBindingInterface; ASection: TDelphiXMLSection); +begin + if not AItem.IsCollection then + Exit; + + case ASection of + dxsInterface: + begin + AStream.WriteLnNamedFmt(EnumeratorInterface, + ['Name', AItem.TranslatedName, + 'ItemName', AItem.CollectionItem.TranslatedName, + 'GUID', CreateNewGUID]); + AStream.WriteLn(''); + end; + + dxsClass: + begin + AStream.WriteLnNamedFmt(EnumeratorClass, + ['Name', AItem.TranslatedName, + 'ItemName', AItem.CollectionItem.TranslatedName]); + AStream.WriteLn(''); + end; + + dxsImplementation: + begin + AStream.WriteLnNamedFmt(EnumeratorImplementation, + ['Name', AItem.TranslatedName, + 'ItemName', AItem.CollectionItem.TranslatedName]); + end; + end; +end; + + function TDelphiXMLDataBindingGenerator.GetDelphiNodeType(AProperty: TXMLDataBindingProperty): TDelphiNodeType; begin if AProperty.IsAttribute then diff --git a/Units/DelphiXMLDataBindingResources.pas b/Units/DelphiXMLDataBindingResources.pas index 266bfb5..90abc0d 100644 --- a/Units/DelphiXMLDataBindingResources.pas +++ b/Units/DelphiXMLDataBindingResources.pas @@ -98,6 +98,31 @@ const XSDValidateMethodImplementationEnd = 'end;' + CrLf; + EnumeratorMethodInterface = ' function GetEnumerator: IXML%:sEnumerator;'; + EnumeratorMethodImplementation = 'function TXML%:s.GetEnumerator: IXML%:sEnumerator;' + CrLf + + 'begin' + CrLf + + ' Result := TXML%:sEnumerator.Create(Self);' + CrLf + + 'end;' + CrLf; + + + EnumeratorInterface = ' IXML%:sEnumerator = interface' + CrLf + + ' %:s' + CrLf + + ' function GetCurrent: IXML%:s;' + CrLf + + ' function MoveNext: Boolean;' + CrLf + + ' property Current: IXML%:s read GetCurrent;' + CrLf + + ' end;' + CrLf; + + + EnumeratorClass = ' TXML%:sEnumerator = class(TXMLNodeCollectionEnumerator, IXML%:sEnumerator)' + CrLf + + ' protected' + CrLf + + ' function GetCurrent: IXML%:s;' + CrLf + + ' end;' + CrLf; + + EnumeratorImplementation = 'function TXML%:sEnumerator.GetCurrent: IXML%:s;' + CrLf + + 'begin' + CrLf + + ' Result := (inherited GetCurrent as IXML%:s);' + CrLf + + 'end;' + CrLf; + PropertyIntfMethodGetOptional = ' function GetHas%:s: Boolean;'; PropertyIntfMethodGetNil = ' function Get%:sIsNil: Boolean;'; PropertyIntfMethodGetText = ' function Get%:sText: WideString;';