You've already forked lazarus-ccr
+Delphi : QWord = UInt64 for CompilerVersion > 16.0
+THeaderBlockProxy : This class is used as a wrapper to allow a TBaseRemotable instance to be sent and received as a header block +ICallContext.AddHeader() : Overload to support classes that do not inherit from THeaderBlock +TTypeRegistryItem.AddExternalSynonym(), TTypeRegistryItem.IsExternalSynonym() Usefull when a xsd defines a complex type and a "element" which type is the complex one. +TTypeRegistry.FindByDeclaredName(): Add an option to include the external synonyms in the search git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@744 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -123,7 +123,12 @@ type
|
|||||||
function AddHeader(
|
function AddHeader(
|
||||||
const AHeader : THeaderBlock;
|
const AHeader : THeaderBlock;
|
||||||
const AKeepOwnership : Boolean
|
const AKeepOwnership : Boolean
|
||||||
):Integer;
|
):Integer;overload;
|
||||||
|
function AddHeader(
|
||||||
|
const AHeader : TBaseRemotable;
|
||||||
|
const AKeepOwnership : Boolean;
|
||||||
|
const AName : string = ''
|
||||||
|
):Integer;overload;
|
||||||
function GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
function GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
||||||
function GetHeader(const AIndex : Integer) : THeaderBlock;
|
function GetHeader(const AIndex : Integer) : THeaderBlock;
|
||||||
procedure ClearHeaders(const ADirection : THeaderDirection);
|
procedure ClearHeaders(const ADirection : THeaderDirection);
|
||||||
@@ -228,7 +233,12 @@ type
|
|||||||
function AddHeader(
|
function AddHeader(
|
||||||
const AHeader : THeaderBlock;
|
const AHeader : THeaderBlock;
|
||||||
const AKeepOwnership : Boolean
|
const AKeepOwnership : Boolean
|
||||||
):Integer;
|
):Integer;overload;
|
||||||
|
function AddHeader(
|
||||||
|
const AHeader : TBaseRemotable;
|
||||||
|
const AKeepOwnership : Boolean;
|
||||||
|
const AName : string = ''
|
||||||
|
):Integer;overload;
|
||||||
function GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
function GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
||||||
function GetHeader(const AIndex : Integer) : THeaderBlock;
|
function GetHeader(const AIndex : Integer) : THeaderBlock;
|
||||||
procedure ClearHeaders(const ADirection : THeaderDirection);
|
procedure ClearHeaders(const ADirection : THeaderDirection);
|
||||||
@@ -758,12 +768,18 @@ type
|
|||||||
private
|
private
|
||||||
FDirection: THeaderDirection;
|
FDirection: THeaderDirection;
|
||||||
FmustUnderstand: Integer;
|
FmustUnderstand: Integer;
|
||||||
|
FName: string;
|
||||||
FUnderstood: Boolean;
|
FUnderstood: Boolean;
|
||||||
|
private
|
||||||
function HasmustUnderstand: boolean;
|
function HasmustUnderstand: boolean;
|
||||||
procedure SetmustUnderstand(const AValue: Integer);
|
procedure SetmustUnderstand(const AValue: Integer);
|
||||||
|
protected
|
||||||
|
function GetName: string; virtual;
|
||||||
|
procedure SetName(const AValue: string); virtual;
|
||||||
public
|
public
|
||||||
property Direction : THeaderDirection read FDirection write FDirection;
|
property Direction : THeaderDirection read FDirection write FDirection;
|
||||||
property Understood : Boolean read FUnderstood write FUnderstood;
|
property Understood : Boolean read FUnderstood write FUnderstood;
|
||||||
|
property Name : string read GetName write SetName;
|
||||||
published
|
published
|
||||||
property mustUnderstand : Integer read FmustUnderstand write SetmustUnderstand stored HasmustUnderstand;
|
property mustUnderstand : Integer read FmustUnderstand write SetmustUnderstand stored HasmustUnderstand;
|
||||||
end;
|
end;
|
||||||
@@ -790,7 +806,40 @@ type
|
|||||||
);override;
|
);override;
|
||||||
property Value : string read FValue write FValue;
|
property Value : string read FValue write FValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ THeaderBlockProxy
|
||||||
|
This class is used as a wrapper to allow a TBaseRemotable instance to be
|
||||||
|
sent and received as a header block.
|
||||||
|
}
|
||||||
|
THeaderBlockProxy = class(THeaderBlock)
|
||||||
|
private
|
||||||
|
FActualObject: TBaseRemotable;
|
||||||
|
FOwnObject: Boolean;
|
||||||
|
FNameSet : Boolean;
|
||||||
|
private
|
||||||
|
procedure SetActualObject(const AValue: TBaseRemotable);
|
||||||
|
protected
|
||||||
|
function GetName : string; override;
|
||||||
|
procedure SetName(const AValue: string); override;
|
||||||
|
public
|
||||||
|
destructor Destroy(); override;
|
||||||
|
class procedure Save(
|
||||||
|
AObject : TBaseRemotable;
|
||||||
|
AStore : IFormatterBase;
|
||||||
|
const AName : string;
|
||||||
|
const ATypeInfo : PTypeInfo
|
||||||
|
);override;
|
||||||
|
class procedure Load(
|
||||||
|
var AObject : TObject;
|
||||||
|
AStore : IFormatterBase;
|
||||||
|
var AName : string;
|
||||||
|
const ATypeInfo : PTypeInfo
|
||||||
|
);override;
|
||||||
|
|
||||||
|
property ActualObject : TBaseRemotable read FActualObject write SetActualObject;
|
||||||
|
property OwnObject : Boolean read FOwnObject write FOwnObject;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TObjectCollectionRemotable
|
{ TObjectCollectionRemotable
|
||||||
An implementation for array handling. The array items are "owned" by
|
An implementation for array handling. The array items are "owned" by
|
||||||
this class instance, so one has not to free them.
|
this class instance, so one has not to free them.
|
||||||
@@ -1434,7 +1483,8 @@ type
|
|||||||
FNameSpace: string;
|
FNameSpace: string;
|
||||||
FDeclaredName : string;
|
FDeclaredName : string;
|
||||||
FOptions: TTypeRegistryItemOptions;
|
FOptions: TTypeRegistryItemOptions;
|
||||||
FSynonymTable : TStrings;
|
FPascalSynonyms : TStrings;
|
||||||
|
FExternalSynonyms : TStrings;
|
||||||
FExternalNames : TStrings;
|
FExternalNames : TStrings;
|
||||||
FInternalNames : TStrings;
|
FInternalNames : TStrings;
|
||||||
private
|
private
|
||||||
@@ -1448,7 +1498,9 @@ type
|
|||||||
);virtual;
|
);virtual;
|
||||||
destructor Destroy();override;
|
destructor Destroy();override;
|
||||||
function AddPascalSynonym(const ASynonym : string):TTypeRegistryItem;
|
function AddPascalSynonym(const ASynonym : string):TTypeRegistryItem;
|
||||||
|
function AddExternalSynonym(const ASynonym : string):TTypeRegistryItem;
|
||||||
function IsSynonym(const APascalTypeName : string):Boolean;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
function IsSynonym(const APascalTypeName : string):Boolean;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
||||||
|
function IsExternalSynonym(const AExternalName : string):Boolean;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
||||||
|
|
||||||
procedure RegisterExternalPropertyName(const APropName, AExtPropName : string);
|
procedure RegisterExternalPropertyName(const APropName, AExtPropName : string);
|
||||||
function GetExternalPropertyName(const APropName : string) : string;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
function GetExternalPropertyName(const APropName : string) : string;{$IFDEF USE_INLINE}inline;{$ENDIF}
|
||||||
@@ -1464,6 +1516,9 @@ type
|
|||||||
property Options : TTypeRegistryItemOptions read FOptions write FOptions;
|
property Options : TTypeRegistryItemOptions read FOptions write FOptions;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TTypeRegistrySearchOption = ( trsoIncludeExternalSynonyms );
|
||||||
|
TTypeRegistrySearchOptions = set of TTypeRegistrySearchOption;
|
||||||
|
|
||||||
{ TTypeRegistry }
|
{ TTypeRegistry }
|
||||||
|
|
||||||
TTypeRegistry = class
|
TTypeRegistry = class
|
||||||
@@ -1491,7 +1546,11 @@ type
|
|||||||
):TTypeRegistryItem;
|
):TTypeRegistryItem;
|
||||||
function Find(ATypeInfo : PTypeInfo; Const AExact : Boolean):TTypeRegistryItem;overload;
|
function Find(ATypeInfo : PTypeInfo; Const AExact : Boolean):TTypeRegistryItem;overload;
|
||||||
function Find(const APascalTypeName : string):TTypeRegistryItem;overload;
|
function Find(const APascalTypeName : string):TTypeRegistryItem;overload;
|
||||||
function FindByDeclaredName(const ATypeName,ANameSpace : string):TTypeRegistryItem;
|
function FindByDeclaredName(
|
||||||
|
const ATypeName,
|
||||||
|
ANameSpace : string;
|
||||||
|
const AOptions : TTypeRegistrySearchOptions = []
|
||||||
|
) : TTypeRegistryItem;
|
||||||
Property Count : Integer Read GetCount;
|
Property Count : Integer Read GetCount;
|
||||||
Property Item[Index:Integer] : TTypeRegistryItem Read GetItemByIndex;default;
|
Property Item[Index:Integer] : TTypeRegistryItem Read GetItemByIndex;default;
|
||||||
Property ItemByTypeInfo[Index:PTypeInfo] : TTypeRegistryItem Read GetItemByTypeInfo;
|
Property ItemByTypeInfo[Index:PTypeInfo] : TTypeRegistryItem Read GetItemByTypeInfo;
|
||||||
@@ -1543,6 +1602,10 @@ const
|
|||||||
const AField : shortstring;
|
const AField : shortstring;
|
||||||
const AVisibility : Boolean
|
const AVisibility : Boolean
|
||||||
);
|
);
|
||||||
|
function GetExternalName(
|
||||||
|
const ATypeInfo : PTypeInfo;
|
||||||
|
const ARegistry : TTypeRegistry = nil
|
||||||
|
) : string;
|
||||||
|
|
||||||
|
|
||||||
function IsStoredPropClass(AClass : TClass;PropInfo : PPropInfo) : TPropStoreType;
|
function IsStoredPropClass(AClass : TClass;PropInfo : PPropInfo) : TPropStoreType;
|
||||||
@@ -1629,6 +1692,8 @@ begin
|
|||||||
ri.Options := ri.Options + [trioNonVisibleToMetadataService];
|
ri.Options := ri.Options + [trioNonVisibleToMetadataService];
|
||||||
ri := r.Register(sSOAP_ENV,TypeInfo(TSimpleContentHeaderBlock));
|
ri := r.Register(sSOAP_ENV,TypeInfo(TSimpleContentHeaderBlock));
|
||||||
ri.Options := ri.Options + [trioNonVisibleToMetadataService];
|
ri.Options := ri.Options + [trioNonVisibleToMetadataService];
|
||||||
|
ri := r.Register(sSOAP_ENV,TypeInfo(THeaderBlockProxy));
|
||||||
|
ri.Options := ri.Options + [trioNonVisibleToMetadataService];
|
||||||
|
|
||||||
|
|
||||||
r.Register(sWST_BASE_NS,TypeInfo(TArrayOfStringRemotable),'TArrayOfStringRemotable').AddPascalSynonym('TArrayOfStringRemotable');
|
r.Register(sWST_BASE_NS,TypeInfo(TArrayOfStringRemotable),'TArrayOfStringRemotable').AddPascalSynonym('TArrayOfStringRemotable');
|
||||||
@@ -1683,6 +1748,25 @@ begin
|
|||||||
r.Register(sXSD_NS,TypeInfo(TBase16StringExtRemotable),'hexBinary').AddPascalSynonym('TBase16StringExtRemotable');
|
r.Register(sXSD_NS,TypeInfo(TBase16StringExtRemotable),'hexBinary').AddPascalSynonym('TBase16StringExtRemotable');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function GetExternalName(
|
||||||
|
const ATypeInfo : PTypeInfo;
|
||||||
|
const ARegistry : TTypeRegistry
|
||||||
|
) : string;
|
||||||
|
var
|
||||||
|
locReg : TTypeRegistry;
|
||||||
|
locRegItem : TTypeRegistryItem;
|
||||||
|
begin
|
||||||
|
if ( ARegistry = nil ) then
|
||||||
|
locReg := GetTypeRegistry()
|
||||||
|
else
|
||||||
|
locReg := ARegistry;
|
||||||
|
locRegItem := locReg.Find(ATypeInfo,False);
|
||||||
|
if ( locRegItem <> nil ) then
|
||||||
|
Result := locRegItem.DeclaredName
|
||||||
|
else
|
||||||
|
Result := ATypeInfo^.Name;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure SetFieldSerializationVisibility(
|
procedure SetFieldSerializationVisibility(
|
||||||
const ATypeInfo : PTypeInfo; // must be tkRecord
|
const ATypeInfo : PTypeInfo; // must be tkRecord
|
||||||
const AField : shortstring;
|
const AField : shortstring;
|
||||||
@@ -2766,6 +2850,35 @@ begin
|
|||||||
AddObjectToFree(AHeader);
|
AddObjectToFree(AHeader);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSimpleCallContext.AddHeader(
|
||||||
|
const AHeader : TBaseRemotable;
|
||||||
|
const AKeepOwnership : Boolean;
|
||||||
|
const AName : string = ''
|
||||||
|
) : Integer;
|
||||||
|
var
|
||||||
|
locProxy : THeaderBlockProxy;
|
||||||
|
begin
|
||||||
|
if ( AHeader <> nil ) then begin
|
||||||
|
if AHeader.InheritsFrom(THeaderBlock) then begin
|
||||||
|
if not IsStrEmpty(AName) then
|
||||||
|
THeaderBlock(AHeader).Name := AName;
|
||||||
|
Result := AddHeader(THeaderBlock(AHeader),AKeepOwnership);
|
||||||
|
end else begin
|
||||||
|
locProxy := THeaderBlockProxy.Create();
|
||||||
|
locProxy.ActualObject := AHeader;
|
||||||
|
locProxy.OwnObject := AKeepOwnership;
|
||||||
|
if not IsStrEmpty(AName) then
|
||||||
|
locProxy.Name := AName;
|
||||||
|
Result := AddHeader(locProxy,True);
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
locProxy := THeaderBlockProxy.Create();
|
||||||
|
if not IsStrEmpty(AName) then
|
||||||
|
locProxy.Name := AName;
|
||||||
|
Result := AddHeader(locProxy,True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TSimpleCallContext.GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
function TSimpleCallContext.GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
||||||
var
|
var
|
||||||
i : Integer;
|
i : Integer;
|
||||||
@@ -2885,7 +2998,8 @@ begin
|
|||||||
FreeObjects();
|
FreeObjects();
|
||||||
FInternalNames.Free();
|
FInternalNames.Free();
|
||||||
FExternalNames.Free();
|
FExternalNames.Free();
|
||||||
FSynonymTable.Free();
|
FPascalSynonyms.Free();
|
||||||
|
FExternalSynonyms.Free();
|
||||||
inherited Destroy();
|
inherited Destroy();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -2894,19 +3008,39 @@ begin
|
|||||||
Result := Self;
|
Result := Self;
|
||||||
if AnsiSameText(ASynonym,DataType^.Name) then
|
if AnsiSameText(ASynonym,DataType^.Name) then
|
||||||
Exit;
|
Exit;
|
||||||
if not Assigned(FSynonymTable) then begin
|
if not Assigned(FPascalSynonyms) then begin
|
||||||
FSynonymTable := TStringList.Create();
|
FPascalSynonyms := TStringList.Create();
|
||||||
FSynonymTable.Add(FDataType^.Name);
|
FPascalSynonyms.Add(FDataType^.Name);
|
||||||
end;
|
end;
|
||||||
if ( FSynonymTable.IndexOf(ASynonym) = -1 ) then
|
if ( FPascalSynonyms.IndexOf(ASynonym) = -1 ) then
|
||||||
FSynonymTable.Add(AnsiLowerCase(ASynonym));
|
FPascalSynonyms.Add(AnsiLowerCase(ASynonym));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTypeRegistryItem.AddExternalSynonym(const ASynonym: string): TTypeRegistryItem;
|
||||||
|
begin
|
||||||
|
Result := Self;
|
||||||
|
if AnsiSameText(ASynonym,DataType^.Name) then
|
||||||
|
Exit;
|
||||||
|
if not Assigned(FExternalSynonyms) then begin
|
||||||
|
FExternalSynonyms := TStringList.Create();
|
||||||
|
FExternalSynonyms.Add(Self.DeclaredName);
|
||||||
|
end;
|
||||||
|
if ( FExternalSynonyms.IndexOf(ASynonym) = -1 ) then
|
||||||
|
FExternalSynonyms.Add(AnsiLowerCase(ASynonym));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTypeRegistryItem.IsSynonym(const APascalTypeName: string): Boolean;
|
function TTypeRegistryItem.IsSynonym(const APascalTypeName: string): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := AnsiSameText(APascalTypeName,DataType^.Name);
|
Result := AnsiSameText(APascalTypeName,DataType^.Name);
|
||||||
if ( not Result ) and Assigned(FSynonymTable) then
|
if ( not Result ) and Assigned(FPascalSynonyms) then
|
||||||
Result := ( FSynonymTable.IndexOf(APascalTypeName) >= 0 ) ;
|
Result := ( FPascalSynonyms.IndexOf(APascalTypeName) >= 0 ) ;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTypeRegistryItem.IsExternalSynonym(const AExternalName: string): Boolean;
|
||||||
|
begin
|
||||||
|
Result := AnsiSameText(AExternalName,Self.DeclaredName);
|
||||||
|
if ( not Result ) and Assigned(FExternalSynonyms) then
|
||||||
|
Result := ( FExternalSynonyms.IndexOf(AExternalName) >= 0 ) ;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTypeRegistryItem.RegisterExternalPropertyName(const APropName,AExtPropName: string);
|
procedure TTypeRegistryItem.RegisterExternalPropertyName(const APropName,AExtPropName: string);
|
||||||
@@ -3119,18 +3253,33 @@ end;
|
|||||||
|
|
||||||
function TTypeRegistry.FindByDeclaredName(
|
function TTypeRegistry.FindByDeclaredName(
|
||||||
const ATypeName,
|
const ATypeName,
|
||||||
ANameSpace : string
|
ANameSpace : string;
|
||||||
|
const AOptions : TTypeRegistrySearchOptions
|
||||||
): TTypeRegistryItem;
|
): TTypeRegistryItem;
|
||||||
var
|
var
|
||||||
i, c : Integer;
|
i, c : Integer;
|
||||||
begin
|
begin
|
||||||
|
{ The external synonym is not tested in the first loop so that the declared
|
||||||
|
names are _first_ search for.
|
||||||
|
}
|
||||||
c := Count;
|
c := Count;
|
||||||
for i := 0 to Pred(c) do begin
|
if ( c > 0 ) then begin
|
||||||
Result := Item[i];
|
for i := 0 to Pred(c) do begin
|
||||||
if AnsiSameText(ANameSpace,Result.NameSpace) and
|
Result := Item[i];
|
||||||
AnsiSameText(ATypeName,Result.DeclaredName)
|
if AnsiSameText(ANameSpace,Result.NameSpace) and
|
||||||
then
|
AnsiSameText(ATypeName,Result.DeclaredName)
|
||||||
Exit;
|
then
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if ( trsoIncludeExternalSynonyms in AOptions ) then begin
|
||||||
|
for i := 0 to Pred(c) do begin
|
||||||
|
Result := Item[i];
|
||||||
|
if AnsiSameText(ANameSpace,Result.NameSpace) and
|
||||||
|
Result.IsExternalSynonym(ATypeName)
|
||||||
|
then
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
@@ -4429,6 +4578,13 @@ begin
|
|||||||
Result := ( FmustUnderstand <> 0 );
|
Result := ( FmustUnderstand <> 0 );
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function THeaderBlock.GetName : string;
|
||||||
|
begin
|
||||||
|
if IsStrEmpty(FName) then
|
||||||
|
FName := GetExternalName(PTypeInfo(Self.ClassInfo));
|
||||||
|
Result := FName;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure THeaderBlock.SetmustUnderstand(const AValue: Integer);
|
procedure THeaderBlock.SetmustUnderstand(const AValue: Integer);
|
||||||
begin
|
begin
|
||||||
if ( AValue <> 0 ) then
|
if ( AValue <> 0 ) then
|
||||||
@@ -4437,6 +4593,11 @@ begin
|
|||||||
FmustUnderstand := 0;
|
FmustUnderstand := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure THeaderBlock.SetName(const AValue: string);
|
||||||
|
begin
|
||||||
|
FName := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSimpleContentHeaderBlock }
|
{ TSimpleContentHeaderBlock }
|
||||||
|
|
||||||
class procedure TSimpleContentHeaderBlock.Save(
|
class procedure TSimpleContentHeaderBlock.Save(
|
||||||
@@ -4498,6 +4659,91 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ THeaderBlockProxy }
|
||||||
|
|
||||||
|
procedure THeaderBlockProxy.SetActualObject(const AValue: TBaseRemotable);
|
||||||
|
var
|
||||||
|
locObj : TObject;
|
||||||
|
begin
|
||||||
|
if ( FActualObject <> AValue ) then begin
|
||||||
|
if OwnObject and ( FActualObject <> nil ) then begin
|
||||||
|
locObj := FActualObject;
|
||||||
|
FActualObject := nil;
|
||||||
|
locObj.Free();
|
||||||
|
end;
|
||||||
|
FActualObject := AValue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function THeaderBlockProxy.GetName : string;
|
||||||
|
begin
|
||||||
|
if FNameSet then
|
||||||
|
Result := inherited GetName()
|
||||||
|
else if ( ActualObject <> nil ) then
|
||||||
|
Result := GetExternalName(PTypeInfo(ActualObject.ClassInfo))
|
||||||
|
else
|
||||||
|
Result := Self.ClassName();
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure THeaderBlockProxy.SetName(const AValue: string);
|
||||||
|
begin
|
||||||
|
inherited SetName(AValue);
|
||||||
|
FNameSet := not IsStrEmpty(AValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor THeaderBlockProxy.Destroy();
|
||||||
|
begin
|
||||||
|
if OwnObject then
|
||||||
|
ActualObject.Free();
|
||||||
|
inherited Destroy();
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THeaderBlockProxy.Save(
|
||||||
|
AObject : TBaseRemotable;
|
||||||
|
AStore : IFormatterBase;
|
||||||
|
const AName : string;
|
||||||
|
const ATypeInfo : PTypeInfo
|
||||||
|
);
|
||||||
|
var
|
||||||
|
locObj : THeaderBlockProxy;
|
||||||
|
begin
|
||||||
|
if ( AObject <> nil ) and AObject.InheritsFrom(THeaderBlockProxy) then begin
|
||||||
|
locObj := THeaderBlockProxy(AObject);
|
||||||
|
if ( locObj.ActualObject <> nil ) then
|
||||||
|
locObj.ActualObject.Save(
|
||||||
|
locObj.ActualObject,
|
||||||
|
AStore,
|
||||||
|
AName,
|
||||||
|
PTypeInfo(locObj.ActualObject.ClassInfo)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure THeaderBlockProxy.Load(
|
||||||
|
var AObject : TObject;
|
||||||
|
AStore : IFormatterBase;
|
||||||
|
var AName : string;
|
||||||
|
const ATypeInfo : PTypeInfo
|
||||||
|
);
|
||||||
|
var
|
||||||
|
locObj : THeaderBlockProxy;
|
||||||
|
locActualObj : TObject;
|
||||||
|
begin
|
||||||
|
if ( AObject <> nil ) and AObject.InheritsFrom(THeaderBlockProxy) then begin
|
||||||
|
locObj := THeaderBlockProxy(AObject);
|
||||||
|
if ( locObj.ActualObject <> nil ) then
|
||||||
|
locActualObj := locObj.ActualObject;
|
||||||
|
locObj.ActualObject.Load(
|
||||||
|
locActualObj,
|
||||||
|
AStore,
|
||||||
|
AName,
|
||||||
|
PTypeInfo(locObj.ActualObject.ClassInfo)
|
||||||
|
);
|
||||||
|
if ( locObj.ActualObject <> locActualObj ) then
|
||||||
|
locObj.ActualObject := TBaseRemotable(locActualObj);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TStoredPropertyManager }
|
{ TStoredPropertyManager }
|
||||||
|
|
||||||
procedure TStoredPropertyManager.Error(Const AMsg: string);
|
procedure TStoredPropertyManager.Error(Const AMsg: string);
|
||||||
|
@@ -441,6 +441,7 @@ type
|
|||||||
|
|
||||||
resourcestring
|
resourcestring
|
||||||
SERR_NodeNotFoundByID = 'Node not found with this ID in the document : %s.';
|
SERR_NodeNotFoundByID = 'Node not found with this ID in the document : %s.';
|
||||||
|
SERR_ExpectingRemotableObjectClass = 'Expecting remotable object class but found %s.';
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
Uses {$IFDEF WST_DELPHI}XMLDoc,XMLIntf,{$ELSE}XMLWrite, XMLRead,wst_fpc_xml,{$ENDIF}
|
Uses {$IFDEF WST_DELPHI}XMLDoc,XMLIntf,{$ELSE}XMLWrite, XMLRead,wst_fpc_xml,{$ENDIF}
|
||||||
@@ -1540,16 +1541,22 @@ function TSOAPBaseFormatter.ReadHeaders(ACallContext: ICallContext): Integer;
|
|||||||
s := sXML_NS + ':' + nsSN;
|
s := sXML_NS + ':' + nsSN;
|
||||||
if not FindAttributeByNameInNode(s,ANode,nsLN) then
|
if not FindAttributeByNameInNode(s,ANode,nsLN) then
|
||||||
nsLN := FindAttributeByNameInScope(s);
|
nsLN := FindAttributeByNameInScope(s);
|
||||||
Result := GetTypeRegistry().FindByDeclaredName(Copy(ndName,Succ(j),MaxInt),nsLN);
|
Result := GetTypeRegistry().FindByDeclaredName(
|
||||||
|
Copy(ndName,Succ(j),MaxInt),
|
||||||
|
nsLN,
|
||||||
|
[trsoIncludeExternalSynonyms]
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
i : Integer;
|
i : Integer;
|
||||||
nd : TDOMElement;
|
nd : TDOMElement;
|
||||||
typItm : TTypeRegistryItem;
|
typItm : TTypeRegistryItem;
|
||||||
tmpObj : THeaderBlock;
|
tmpHeader : THeaderBlock;
|
||||||
locName : string;
|
locName : string;
|
||||||
chdLst : TDOMNodeList;
|
chdLst : TDOMNodeList;
|
||||||
|
typData : PTypeData;
|
||||||
|
tmpObj : TBaseRemotable;
|
||||||
begin
|
begin
|
||||||
SetStyleAndEncoding(Document,Literal);
|
SetStyleAndEncoding(Document,Literal);
|
||||||
try
|
try
|
||||||
@@ -1562,12 +1569,29 @@ begin
|
|||||||
typItm := ExtractTypeInfo(nd);
|
typItm := ExtractTypeInfo(nd);
|
||||||
if Assigned(typItm) then begin
|
if Assigned(typItm) then begin
|
||||||
if ( typItm.DataType^.Kind = tkClass ) then begin
|
if ( typItm.DataType^.Kind = tkClass ) then begin
|
||||||
tmpObj := nil;
|
tmpHeader := nil;
|
||||||
locName := nd.NodeName;
|
locName := nd.NodeName;
|
||||||
Get(typItm.DataType,locName,tmpObj);
|
typData := GetTypeData(typItm.DataType);
|
||||||
if Assigned(tmpObj) then begin
|
if typData^.ClassType.InheritsFrom(THeaderBlock) then begin
|
||||||
tmpObj.Direction := hdIn;
|
Get(typItm.DataType,locName,tmpHeader);
|
||||||
ACallContext.AddHeader(tmpObj,True);
|
if Assigned(tmpHeader) then begin
|
||||||
|
tmpHeader.Direction := hdIn;
|
||||||
|
ACallContext.AddHeader(tmpHeader,True);
|
||||||
|
tmpHeader.Name := ExtractNameFromQualifiedName(locName);
|
||||||
|
end;
|
||||||
|
end else if typData^.ClassType.InheritsFrom(TBaseRemotable) then begin
|
||||||
|
tmpObj := nil;
|
||||||
|
Get(typItm.DataType,locName,tmpObj);
|
||||||
|
if Assigned(tmpObj) then begin
|
||||||
|
tmpHeader := THeaderBlockProxy.Create();
|
||||||
|
THeaderBlockProxy(tmpHeader).ActualObject := tmpObj;
|
||||||
|
THeaderBlockProxy(tmpHeader).OwnObject := True;
|
||||||
|
tmpHeader.Direction := hdIn;
|
||||||
|
ACallContext.AddHeader(tmpHeader,True);
|
||||||
|
tmpHeader.Name := ExtractNameFromQualifiedName(locName);
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
Error(SERR_ExpectingRemotableObjectClass,[typItm.DataType^.Name]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@@ -1596,7 +1620,8 @@ begin
|
|||||||
h := ACallContext.GetHeader(i);
|
h := ACallContext.GetHeader(i);
|
||||||
if ( h.Direction = hdOut ) then begin
|
if ( h.Direction = hdOut ) then begin
|
||||||
ptyp := PTypeInfo(h.ClassInfo);
|
ptyp := PTypeInfo(h.ClassInfo);
|
||||||
Put(GetTypeRegistry().ItemByTypeInfo[ptyp].DeclaredName,ptyp,h);
|
//Put(GetTypeRegistry().ItemByTypeInfo[ptyp].DeclaredName,ptyp,h);
|
||||||
|
Put(h.Name,ptyp,h);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
|
@@ -46,6 +46,7 @@ Type
|
|||||||
function IsStrEmpty(Const AStr:ShortString):Boolean;{$IFDEF USE_INLINE}inline;{$ENDIF}overload;
|
function IsStrEmpty(Const AStr:ShortString):Boolean;{$IFDEF USE_INLINE}inline;{$ENDIF}overload;
|
||||||
function GetToken(var ABuffer : string; const ADelimiter : string): string;
|
function GetToken(var ABuffer : string; const ADelimiter : string): string;
|
||||||
function ExtractOptionName(const ACompleteName : string):string;
|
function ExtractOptionName(const ACompleteName : string):string;
|
||||||
|
function ExtractNameFromQualifiedName(const AQualifiedName : string; const ASeparator : Char = ':') : string;
|
||||||
function TranslateDotToDecimalSeperator(const Value: string) : string;
|
function TranslateDotToDecimalSeperator(const Value: string) : string;
|
||||||
function wst_FormatFloat(
|
function wst_FormatFloat(
|
||||||
const ATypeInfo : PTypeInfo;
|
const ATypeInfo : PTypeInfo;
|
||||||
@@ -101,6 +102,16 @@ begin
|
|||||||
Result := Trim(Result);
|
Result := Trim(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function ExtractNameFromQualifiedName(const AQualifiedName : string; const ASeparator : Char) : string;
|
||||||
|
var
|
||||||
|
sepPos : Integer;
|
||||||
|
begin
|
||||||
|
sepPos := Pos(ASeparator,AQualifiedName);
|
||||||
|
if ( sepPos <= 0 ) then
|
||||||
|
sepPos := 0;
|
||||||
|
Result := Copy(AQualifiedName,(sepPos + 1),Length(AQualifiedName));
|
||||||
|
end;
|
||||||
|
|
||||||
function TranslateDotToDecimalSeperator(const Value: string) : string;
|
function TranslateDotToDecimalSeperator(const Value: string) : string;
|
||||||
var
|
var
|
||||||
i : PtrInt;
|
i : PtrInt;
|
||||||
|
@@ -19,11 +19,8 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, TypInfo, Contnrs,
|
Classes, SysUtils, TypInfo, Contnrs,
|
||||||
base_service_intf;
|
base_service_intf, wst_types;
|
||||||
|
|
||||||
{$INCLUDE wst.inc}
|
|
||||||
{$INCLUDE wst_delphi.inc}
|
|
||||||
|
|
||||||
Const
|
Const
|
||||||
sTARGET = 'target';
|
sTARGET = 'target';
|
||||||
|
|
||||||
@@ -99,7 +96,12 @@ Type
|
|||||||
function AddHeader(
|
function AddHeader(
|
||||||
const AHeader : THeaderBlock;
|
const AHeader : THeaderBlock;
|
||||||
const AKeepOwnership : Boolean
|
const AKeepOwnership : Boolean
|
||||||
):Integer;
|
):Integer;overload;
|
||||||
|
function AddHeader(
|
||||||
|
const AHeader : TBaseRemotable;
|
||||||
|
const AKeepOwnership : Boolean;
|
||||||
|
const AName : string = ''
|
||||||
|
):Integer;overload;
|
||||||
function GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
function GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
||||||
function GetHeader(const AIndex : Integer) : THeaderBlock;
|
function GetHeader(const AIndex : Integer) : THeaderBlock;
|
||||||
// ---- END >> ICallContext implementation ----
|
// ---- END >> ICallContext implementation ----
|
||||||
@@ -267,6 +269,15 @@ begin
|
|||||||
Result := FCallContext.AddHeader(AHeader,AKeepOwnership);
|
Result := FCallContext.AddHeader(AHeader,AKeepOwnership);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TBaseProxy.AddHeader(
|
||||||
|
const AHeader : TBaseRemotable;
|
||||||
|
const AKeepOwnership : Boolean;
|
||||||
|
const AName : string = ''
|
||||||
|
): Integer;
|
||||||
|
begin
|
||||||
|
Result := FCallContext.AddHeader(AHeader,AKeepOwnership,AName);
|
||||||
|
end;
|
||||||
|
|
||||||
function TBaseProxy.GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
function TBaseProxy.GetHeaderCount(const ADirections : THeaderDirections):Integer;
|
||||||
begin
|
begin
|
||||||
Result := FCallContext.GetHeaderCount(ADirections);
|
Result := FCallContext.GetHeaderCount(ADirections);
|
||||||
|
@@ -33,6 +33,28 @@ type
|
|||||||
|
|
||||||
TSOAPTestEnum = ( steOne, steTwo, steThree, steFour );
|
TSOAPTestEnum = ( steOne, steTwo, steThree, steFour );
|
||||||
|
|
||||||
|
{ TLoginInfos }
|
||||||
|
|
||||||
|
TLoginInfos = class(TBaseComplexRemotable)
|
||||||
|
private
|
||||||
|
FPassword: string;
|
||||||
|
FUserName: string;
|
||||||
|
published
|
||||||
|
property UserName : string read FUserName write FUserName;
|
||||||
|
property Password : string read FPassword write FPassword;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ THeaderProxyTestObject }
|
||||||
|
|
||||||
|
THeaderProxyTestObject = class(TBaseComplexRemotable)
|
||||||
|
private
|
||||||
|
FDestructionCount: PInteger;
|
||||||
|
procedure SetDestructionCount(const AValue: PInteger);
|
||||||
|
public
|
||||||
|
destructor Destroy(); override;
|
||||||
|
property DestructionCount : PInteger read FDestructionCount write SetDestructionCount;
|
||||||
|
end;
|
||||||
|
|
||||||
{ NBHeader }
|
{ NBHeader }
|
||||||
|
|
||||||
NBHeader = class(THeaderBlock)
|
NBHeader = class(THeaderBlock)
|
||||||
@@ -130,9 +152,15 @@ type
|
|||||||
TTest_SoapFormatterHeader = class(TTestCase)
|
TTest_SoapFormatterHeader = class(TTestCase)
|
||||||
published
|
published
|
||||||
procedure write_header_simple_content_1();
|
procedure write_header_simple_content_1();
|
||||||
|
procedure write_header_simple_content_1_b();
|
||||||
procedure write_header_simple_content_2();
|
procedure write_header_simple_content_2();
|
||||||
procedure read_header_simple_content_1();
|
procedure read_header_simple_content_1();
|
||||||
procedure read_header_simple_content_2();
|
procedure read_header_simple_content_2();
|
||||||
|
|
||||||
|
procedure write_header_proxy_header_block();
|
||||||
|
procedure write_header_proxy_header_block_name();
|
||||||
|
procedure read_header_proxy_header_block();
|
||||||
|
procedure read_header_proxy_header_block_name();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
THRefTestSession = class(TBaseComplexRemotable)
|
THRefTestSession = class(TBaseComplexRemotable)
|
||||||
@@ -151,6 +179,15 @@ type
|
|||||||
procedure test_soap_href_id();
|
procedure test_soap_href_id();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TTest_THeaderBlockProxy }
|
||||||
|
|
||||||
|
TTest_THeaderBlockProxy = class(TTestCase)
|
||||||
|
published
|
||||||
|
procedure ActualObject;
|
||||||
|
procedure OwnObject_Destroy;
|
||||||
|
procedure OwnObject_SetActualObject;
|
||||||
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
uses
|
uses
|
||||||
object_serializer, server_service_soap, test_suite_utils, soap_formatter;
|
object_serializer, server_service_soap, test_suite_utils, soap_formatter;
|
||||||
@@ -489,6 +526,39 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTest_SoapFormatterHeader.write_header_simple_content_1_b();
|
||||||
|
var
|
||||||
|
ser : IFormatterClient;
|
||||||
|
cc : ICallContext;
|
||||||
|
hdr : TSampleSimpleContentHeaderBlock_A;
|
||||||
|
locStream : TMemoryStream;
|
||||||
|
locDoc, locExistDoc : TXMLDocument;
|
||||||
|
begin
|
||||||
|
cc := TSimpleCallContext.Create();
|
||||||
|
hdr := TSampleSimpleContentHeaderBlock_A.Create();
|
||||||
|
cc.AddHeader(TBaseRemotable(hdr),True);
|
||||||
|
hdr.Direction := hdOut;
|
||||||
|
hdr.Value := 'sample header simple content value';
|
||||||
|
ser := soap_formatter.TSOAPFormatter.Create();
|
||||||
|
ser.BeginCall('test_proc','TestService',cc);
|
||||||
|
ser.EndScope();
|
||||||
|
locDoc := nil;
|
||||||
|
locExistDoc := nil;
|
||||||
|
locStream := TMemoryStream.Create();
|
||||||
|
try
|
||||||
|
ser.SaveToStream(locStream);
|
||||||
|
//locStream.SaveToFile(wstExpandLocalFileName('write_header_simple_content_1.xml'));
|
||||||
|
locStream.Position := 0;
|
||||||
|
ReadXMLFile(locDoc,locStream);
|
||||||
|
ReadXMLFile(locExistDoc,wstExpandLocalFileName(TestFilesPath + 'write_header_simple_content_1.xml'));
|
||||||
|
Check(CompareNodes(locExistDoc.DocumentElement,locDoc.DocumentElement),'generated document differs from the existent one.');
|
||||||
|
finally
|
||||||
|
ReleaseDomNode(locDoc);
|
||||||
|
ReleaseDomNode(locExistDoc);
|
||||||
|
locStream.Free();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTest_SoapFormatterHeader.write_header_simple_content_2();
|
procedure TTest_SoapFormatterHeader.write_header_simple_content_2();
|
||||||
var
|
var
|
||||||
ser : IFormatterClient;
|
ser : IFormatterClient;
|
||||||
@@ -623,6 +693,175 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTest_SoapFormatterHeader.write_header_proxy_header_block();
|
||||||
|
var
|
||||||
|
ser : IFormatterClient;
|
||||||
|
cc : ICallContext;
|
||||||
|
locLoginInfo : TLoginInfos;
|
||||||
|
locStream : TMemoryStream;
|
||||||
|
locDoc, locExistDoc : TXMLDocument;
|
||||||
|
begin
|
||||||
|
cc := TSimpleCallContext.Create();
|
||||||
|
locLoginInfo := TLoginInfos.Create();
|
||||||
|
locLoginInfo.UserName := 'Inoussa-wst';
|
||||||
|
locLoginInfo.Password := 'sample password';
|
||||||
|
cc.AddHeader(locLoginInfo,True);
|
||||||
|
ser := soap_formatter.TSOAPFormatter.Create();
|
||||||
|
ser.BeginCall('test_proc','TestService',cc);
|
||||||
|
ser.EndScope();
|
||||||
|
locDoc := nil;
|
||||||
|
locExistDoc := nil;
|
||||||
|
locStream := TMemoryStream.Create();
|
||||||
|
try
|
||||||
|
ser.SaveToStream(locStream);
|
||||||
|
locStream.SaveToFile(wstExpandLocalFileName('write_header_proxy_header_block.xml'));
|
||||||
|
locStream.Position := 0;
|
||||||
|
ReadXMLFile(locDoc,locStream);
|
||||||
|
ReadXMLFile(locExistDoc,wstExpandLocalFileName(TestFilesPath + 'write_header_proxy_header_block.xml'));
|
||||||
|
Check(CompareNodes(locExistDoc.DocumentElement,locDoc.DocumentElement),'generated document differs from the existent one.');
|
||||||
|
finally
|
||||||
|
ReleaseDomNode(locDoc);
|
||||||
|
ReleaseDomNode(locExistDoc);
|
||||||
|
locStream.Free();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTest_SoapFormatterHeader.write_header_proxy_header_block_name();
|
||||||
|
var
|
||||||
|
ser : IFormatterClient;
|
||||||
|
cc : ICallContext;
|
||||||
|
locLoginInfo : TLoginInfos;
|
||||||
|
locStream : TMemoryStream;
|
||||||
|
locDoc, locExistDoc : TXMLDocument;
|
||||||
|
begin
|
||||||
|
cc := TSimpleCallContext.Create();
|
||||||
|
locLoginInfo := TLoginInfos.Create();
|
||||||
|
locLoginInfo.UserName := 'Inoussa-wst';
|
||||||
|
locLoginInfo.Password := 'sample password';
|
||||||
|
cc.AddHeader(locLoginInfo,True,'NamedLoginInfos');
|
||||||
|
ser := soap_formatter.TSOAPFormatter.Create();
|
||||||
|
ser.BeginCall('test_proc','TestService',cc);
|
||||||
|
ser.EndScope();
|
||||||
|
locDoc := nil;
|
||||||
|
locExistDoc := nil;
|
||||||
|
locStream := TMemoryStream.Create();
|
||||||
|
try
|
||||||
|
ser.SaveToStream(locStream);
|
||||||
|
locStream.SaveToFile(wstExpandLocalFileName('write_header_proxy_header_block_name.xml'));
|
||||||
|
locStream.Position := 0;
|
||||||
|
ReadXMLFile(locDoc,locStream);
|
||||||
|
ReadXMLFile(locExistDoc,wstExpandLocalFileName(TestFilesPath + 'write_header_proxy_header_block_name.xml'));
|
||||||
|
Check(CompareNodes(locExistDoc.DocumentElement,locDoc.DocumentElement),'generated document differs from the existent one.');
|
||||||
|
finally
|
||||||
|
ReleaseDomNode(locDoc);
|
||||||
|
ReleaseDomNode(locExistDoc);
|
||||||
|
locStream.Free();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTest_SoapFormatterHeader.read_header_proxy_header_block();
|
||||||
|
const
|
||||||
|
XML_SOURCE =
|
||||||
|
'<?xml version="1.0"?>' + sLineBreak +
|
||||||
|
'<SOAP-ENV:Envelope ' + sLineBreak +
|
||||||
|
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' + sLineBreak +
|
||||||
|
' xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" ' + sLineBreak +
|
||||||
|
' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ' + sLineBreak +
|
||||||
|
' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' + sLineBreak +
|
||||||
|
' <SOAP-ENV:Header xmlns:ns1="soap.test.namespace">' + sLineBreak +
|
||||||
|
' <ns1:LoginInfos >' + sLineBreak +
|
||||||
|
' <ns1:UserName>Inoussa-wst</ns1:UserName>' + sLineBreak +
|
||||||
|
' <ns1:Password>sample password</ns1:Password>' + sLineBreak +
|
||||||
|
' </ns1:LoginInfos>' + sLineBreak +
|
||||||
|
' </SOAP-ENV:Header>' + sLineBreak +
|
||||||
|
' <SOAP-ENV:Body>' + sLineBreak +
|
||||||
|
' <ns2:test_proc xmlns:ns2="TestService"/>' + sLineBreak +
|
||||||
|
' </SOAP-ENV:Body>' + sLineBreak +
|
||||||
|
'</SOAP-ENV:Envelope>';
|
||||||
|
var
|
||||||
|
f : IFormatterClient;
|
||||||
|
strm : TMemoryStream;
|
||||||
|
strBuffer : ansistring;
|
||||||
|
cctx : ICallContext;
|
||||||
|
hdr : THeaderBlockProxy;
|
||||||
|
actualHeader : TLoginInfos;
|
||||||
|
begin
|
||||||
|
f := soap_formatter.TSOAPFormatter.Create() as IFormatterClient;
|
||||||
|
strm := TMemoryStream.Create();
|
||||||
|
try
|
||||||
|
strBuffer := XML_SOURCE;
|
||||||
|
strm.Write(strBuffer[1],Length(strBuffer));
|
||||||
|
strm.Position := 0;
|
||||||
|
f.LoadFromStream(strm);
|
||||||
|
cctx := TSimpleCallContext.Create() as ICallContext;
|
||||||
|
f.BeginCallRead(cctx);
|
||||||
|
CheckEquals(0,cctx.GetHeaderCount([hdOut]),'Ouput header count');
|
||||||
|
CheckEquals(1,cctx.GetHeaderCount([hdIn]),'Input header count');
|
||||||
|
CheckIs(cctx.GetHeader(0),THeaderBlockProxy);
|
||||||
|
hdr := THeaderBlockProxy(cctx.GetHeader(0));
|
||||||
|
CheckIs(hdr.ActualObject,TLoginInfos);
|
||||||
|
actualHeader := TLoginInfos(hdr.ActualObject);
|
||||||
|
//CheckEquals(1,hdr.mustUnderstand,'mustUnderstand');
|
||||||
|
CheckEquals('LoginInfos',hdr.Name,'Name');
|
||||||
|
CheckEquals('Inoussa-wst',actualHeader.UserName,'UserName');
|
||||||
|
CheckEquals('sample password',actualHeader.Password,'Password');
|
||||||
|
f.EndScopeRead();
|
||||||
|
finally
|
||||||
|
FreeAndNil(strm);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTest_SoapFormatterHeader.read_header_proxy_header_block_name();
|
||||||
|
const
|
||||||
|
XML_SOURCE =
|
||||||
|
'<?xml version="1.0"?>' + sLineBreak +
|
||||||
|
'<SOAP-ENV:Envelope ' + sLineBreak +
|
||||||
|
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' + sLineBreak +
|
||||||
|
' xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" ' + sLineBreak +
|
||||||
|
' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" ' + sLineBreak +
|
||||||
|
' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' + sLineBreak +
|
||||||
|
' <SOAP-ENV:Header xmlns:ns1="soap.test.namespace">' + sLineBreak +
|
||||||
|
' <ns1:NamedLoginInfos >' + sLineBreak +
|
||||||
|
' <ns1:UserName>Inoussa-wst</ns1:UserName>' + sLineBreak +
|
||||||
|
' <ns1:Password>sample password</ns1:Password>' + sLineBreak +
|
||||||
|
' </ns1:NamedLoginInfos>' + sLineBreak +
|
||||||
|
' </SOAP-ENV:Header>' + sLineBreak +
|
||||||
|
' <SOAP-ENV:Body>' + sLineBreak +
|
||||||
|
' <ns2:test_proc xmlns:ns2="TestService"/>' + sLineBreak +
|
||||||
|
' </SOAP-ENV:Body>' + sLineBreak +
|
||||||
|
'</SOAP-ENV:Envelope>';
|
||||||
|
var
|
||||||
|
f : IFormatterClient;
|
||||||
|
strm : TMemoryStream;
|
||||||
|
strBuffer : ansistring;
|
||||||
|
cctx : ICallContext;
|
||||||
|
hdr : THeaderBlockProxy;
|
||||||
|
actualHeader : TLoginInfos;
|
||||||
|
begin
|
||||||
|
f := soap_formatter.TSOAPFormatter.Create() as IFormatterClient;
|
||||||
|
strm := TMemoryStream.Create();
|
||||||
|
try
|
||||||
|
strBuffer := XML_SOURCE;
|
||||||
|
strm.Write(strBuffer[1],Length(strBuffer));
|
||||||
|
strm.Position := 0;
|
||||||
|
f.LoadFromStream(strm);
|
||||||
|
cctx := TSimpleCallContext.Create() as ICallContext;
|
||||||
|
f.BeginCallRead(cctx);
|
||||||
|
CheckEquals(0,cctx.GetHeaderCount([hdOut]),'Ouput header count');
|
||||||
|
CheckEquals(1,cctx.GetHeaderCount([hdIn]),'Input header count');
|
||||||
|
CheckIs(cctx.GetHeader(0),THeaderBlockProxy);
|
||||||
|
hdr := THeaderBlockProxy(cctx.GetHeader(0));
|
||||||
|
CheckIs(hdr.ActualObject,TLoginInfos);
|
||||||
|
actualHeader := TLoginInfos(hdr.ActualObject);
|
||||||
|
CheckEquals('NamedLoginInfos',hdr.Name,'Name');
|
||||||
|
CheckEquals('Inoussa-wst',actualHeader.UserName,'UserName');
|
||||||
|
CheckEquals('sample password',actualHeader.Password,'Password');
|
||||||
|
f.EndScopeRead();
|
||||||
|
finally
|
||||||
|
FreeAndNil(strm);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TTest_SoapFormatterClient }
|
{ TTest_SoapFormatterClient }
|
||||||
|
|
||||||
procedure TTest_SoapFormatterClient.test_soap_href_id();
|
procedure TTest_SoapFormatterClient.test_soap_href_id();
|
||||||
@@ -674,6 +913,92 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ THeaderProxyTestObject }
|
||||||
|
|
||||||
|
procedure THeaderProxyTestObject.SetDestructionCount(const AValue: PInteger);
|
||||||
|
begin
|
||||||
|
if ( FDestructionCount = AValue ) then
|
||||||
|
Exit;
|
||||||
|
FDestructionCount := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor THeaderProxyTestObject.Destroy();
|
||||||
|
begin
|
||||||
|
if ( FDestructionCount <> nil ) then
|
||||||
|
Inc(FDestructionCount^);
|
||||||
|
inherited Destroy();
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TTest_THeaderBlockProxy }
|
||||||
|
|
||||||
|
procedure TTest_THeaderBlockProxy.ActualObject;
|
||||||
|
var
|
||||||
|
locObj : THeaderBlockProxy;
|
||||||
|
ao1, ao2 : THeaderProxyTestObject;
|
||||||
|
begin
|
||||||
|
ao1 := nil;
|
||||||
|
ao2 := nil;
|
||||||
|
locObj := THeaderBlockProxy.Create();
|
||||||
|
try
|
||||||
|
CheckNull(locObj.ActualObject);
|
||||||
|
CheckEquals(False, locObj.OwnObject);
|
||||||
|
ao1 := THeaderProxyTestObject.Create();
|
||||||
|
ao2 := THeaderProxyTestObject.Create();
|
||||||
|
|
||||||
|
locObj.ActualObject := ao1;
|
||||||
|
CheckSame(ao1, locObj.ActualObject);
|
||||||
|
locObj.ActualObject := ao2;
|
||||||
|
CheckSame(ao2,locObj.ActualObject);
|
||||||
|
locObj.ActualObject := nil;
|
||||||
|
CheckNull(locObj.ActualObject);
|
||||||
|
finally
|
||||||
|
locObj.Free();
|
||||||
|
ao1.Free();
|
||||||
|
ao2.Free();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTest_THeaderBlockProxy.OwnObject_Destroy;
|
||||||
|
var
|
||||||
|
locObj : THeaderBlockProxy;
|
||||||
|
ao1 : THeaderProxyTestObject;
|
||||||
|
locDestructionCount : Integer;
|
||||||
|
begin
|
||||||
|
locDestructionCount := 0;
|
||||||
|
ao1 := nil;
|
||||||
|
locObj := THeaderBlockProxy.Create();
|
||||||
|
ao1 := THeaderProxyTestObject.Create();
|
||||||
|
locObj.ActualObject := ao1;
|
||||||
|
locObj.OwnObject := True;
|
||||||
|
ao1.DestructionCount := @locDestructionCount;
|
||||||
|
locObj.Free();
|
||||||
|
CheckEquals(1,locDestructionCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTest_THeaderBlockProxy.OwnObject_SetActualObject;
|
||||||
|
var
|
||||||
|
locObj : THeaderBlockProxy;
|
||||||
|
ao1, ao2 : THeaderProxyTestObject;
|
||||||
|
locDestructionCount : Integer;
|
||||||
|
begin
|
||||||
|
locDestructionCount := 0;
|
||||||
|
ao1 := nil;
|
||||||
|
locObj := THeaderBlockProxy.Create();
|
||||||
|
ao1 := THeaderProxyTestObject.Create();
|
||||||
|
ao1.DestructionCount := @locDestructionCount;
|
||||||
|
ao2 := THeaderProxyTestObject.Create();
|
||||||
|
ao2.DestructionCount := @locDestructionCount;
|
||||||
|
locObj.OwnObject := True;
|
||||||
|
|
||||||
|
locObj.ActualObject := ao1;
|
||||||
|
locObj.ActualObject := ao2;
|
||||||
|
CheckEquals(1,locDestructionCount);
|
||||||
|
locObj.ActualObject := ao2;
|
||||||
|
CheckEquals(1,locDestructionCount,'Setting the same value should not free the object.');
|
||||||
|
locObj.Free();
|
||||||
|
CheckEquals(2,locDestructionCount);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
GetTypeRegistry().Register(TSampleSimpleContentHeaderBlock_A.GetNameSpace(),TypeInfo(TSampleSimpleContentHeaderBlock_A));
|
GetTypeRegistry().Register(TSampleSimpleContentHeaderBlock_A.GetNameSpace(),TypeInfo(TSampleSimpleContentHeaderBlock_A));
|
||||||
@@ -686,10 +1011,14 @@ initialization
|
|||||||
GetTypeRegistry().Register(TNameSpaceC_Class.GetNameSpace(),TypeInfo(TNameSpaceC_Class));
|
GetTypeRegistry().Register(TNameSpaceC_Class.GetNameSpace(),TypeInfo(TNameSpaceC_Class));
|
||||||
GetTypeRegistry().Register(ns_soap_test,TypeInfo(TSOAPTestEnum));
|
GetTypeRegistry().Register(ns_soap_test,TypeInfo(TSOAPTestEnum));
|
||||||
GetTypeRegistry().Register('urn:WS_PlotjetIntfU',TypeInfo(THRefTestSession),'TSession');
|
GetTypeRegistry().Register('urn:WS_PlotjetIntfU',TypeInfo(THRefTestSession),'TSession');
|
||||||
|
GetTypeRegistry().Register(ns_soap_test,TypeInfo(TLoginInfos),'LoginInfos').AddExternalSynonym('NamedLoginInfos');
|
||||||
|
GetTypeRegistry().Register(ns_soap_test,TypeInfo(THeaderProxyTestObject));
|
||||||
|
|
||||||
|
|
||||||
RegisterTest('Serializer',TTest_SoapFormatterServerNameSpace.Suite);
|
RegisterTest('Serializer',TTest_SoapFormatterServerNameSpace.Suite);
|
||||||
RegisterTest('Serializer',TTest_SoapFormatterHeader.Suite);
|
RegisterTest('Serializer',TTest_SoapFormatterHeader.Suite);
|
||||||
RegisterTest('Serializer',TTest_SoapFormatterClient.Suite);
|
RegisterTest('Serializer',TTest_SoapFormatterClient.Suite);
|
||||||
|
|
||||||
|
RegisterTest('Support',TTest_THeaderBlockProxy.Suite);
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@@ -103,7 +103,7 @@ type
|
|||||||
class function GetItemClass():TBaseRemotableClass;override;
|
class function GetItemClass():TBaseRemotableClass;override;
|
||||||
property Item[AIndex:Integer] : TClass_A Read GetItem;Default;
|
property Item[AIndex:Integer] : TClass_A Read GetItem;Default;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TTest_TBaseComplexRemotable }
|
{ TTest_TBaseComplexRemotable }
|
||||||
|
|
||||||
TTest_TBaseComplexRemotable = class(TTestCase)
|
TTest_TBaseComplexRemotable = class(TTestCase)
|
||||||
|
@@ -1,6 +1,14 @@
|
|||||||
{$IFNDEF FPC}
|
{$IFDEF DELPHI}
|
||||||
type
|
type
|
||||||
|
{$IFDEF CompilerVersion}
|
||||||
|
{$IF ( CompilerVersion > 16.0 )}
|
||||||
|
QWord = UInt64;
|
||||||
|
{$IFEND}
|
||||||
|
{$ENDIF CompilerVersion}
|
||||||
|
{$IF Not Declared(QWord) }
|
||||||
QWord = type Int64;
|
QWord = type Int64;
|
||||||
|
{$IFEND
|
||||||
|
}
|
||||||
DWORD = LongWord;
|
DWORD = LongWord;
|
||||||
PtrInt = Integer;
|
PtrInt = Integer;
|
||||||
PByteArray = ^ByteArray;
|
PByteArray = ^ByteArray;
|
||||||
@@ -8,4 +16,4 @@
|
|||||||
PtrUInt = Cardinal;
|
PtrUInt = Cardinal;
|
||||||
SizeInt = Longint;
|
SizeInt = Longint;
|
||||||
UnicodeChar = WideChar;
|
UnicodeChar = WideChar;
|
||||||
{$ENDIF}
|
{$ENDIF DELPHI}
|
||||||
|
Reference in New Issue
Block a user