2006-08-26 00:35:42 +00:00
|
|
|
{
|
|
|
|
This file is part of the Web Service Toolkit
|
|
|
|
Copyright (c) 2006 by Inoussa OUEDRAOGO
|
|
|
|
|
|
|
|
This file is provide under modified LGPL licence
|
|
|
|
( the files COPYING.modifiedLGPL and COPYING.LGPL).
|
|
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
}
|
2007-07-12 14:46:45 +00:00
|
|
|
{$INCLUDE wst_global.inc}
|
2006-08-26 00:35:42 +00:00
|
|
|
unit metadata_repository;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2007-04-26 23:23:41 +00:00
|
|
|
Classes, SysUtils, TypInfo;
|
2006-08-26 00:35:42 +00:00
|
|
|
|
|
|
|
const
|
|
|
|
sWST_META = 'wst_meta';
|
2007-04-26 23:23:41 +00:00
|
|
|
sFORMAT = 'FORMAT';
|
|
|
|
sTRANSPORT = 'TRANSPORT';
|
2006-08-26 00:35:42 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
EMetadataException = class(Exception)
|
|
|
|
end;
|
|
|
|
|
|
|
|
PPropertyData = ^TPropertyData;
|
|
|
|
TPropertyData = record
|
|
|
|
Name : string;
|
|
|
|
Data : string;
|
|
|
|
Next : PPropertyData;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TOperationParamFlag = ( opfNone, opfIn, opfVar, opfOut );
|
|
|
|
|
|
|
|
POperationParam = ^TOperationParam;
|
|
|
|
TOperationParam = record
|
|
|
|
Name : ShortString;
|
|
|
|
TypeName : ShortString;
|
|
|
|
Modifier : TOperationParamFlag;
|
|
|
|
end;
|
|
|
|
|
2009-05-25 16:13:54 +00:00
|
|
|
PServiceOperation = ^TServiceOperation;
|
2006-08-26 00:35:42 +00:00
|
|
|
TServiceOperation = record
|
|
|
|
Name : ShortString;
|
|
|
|
ParamsCount : Byte;
|
|
|
|
Params : POperationParam;
|
|
|
|
Properties : PPropertyData;
|
|
|
|
end;
|
|
|
|
|
|
|
|
PService = ^TService;
|
|
|
|
TService = record
|
|
|
|
Name : ShortString;
|
2009-12-01 15:50:52 +00:00
|
|
|
OperationsCount : Word;
|
2006-08-26 00:35:42 +00:00
|
|
|
Operations : PServiceOperation;
|
2007-03-25 23:47:16 +00:00
|
|
|
Properties : PPropertyData;
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
PServiceRepository = ^TServiceRepository;
|
|
|
|
TServiceRepository = record
|
|
|
|
NameSpace : ShortString;
|
|
|
|
Name : ShortString;
|
|
|
|
RootAddress : ShortString;
|
2009-12-01 15:50:52 +00:00
|
|
|
ServicesCount : Word;
|
2006-08-26 00:35:42 +00:00
|
|
|
Services : PService;
|
2015-07-31 13:16:03 +00:00
|
|
|
Properties : PPropertyData;
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
IModuleMetadataMngr = interface
|
|
|
|
['{B10ACF6A-A599-45A3-B083-BEEFB810C889}']
|
|
|
|
function IndexOfName(const ARepName : shortstring):Integer;
|
|
|
|
function GetCount():Integer;
|
|
|
|
function GetRepositoryName(const AIndex : Integer):shortstring;
|
|
|
|
procedure SetRepositoryNameSpace(const ARepName,ANameSpace : shortstring);
|
2015-07-31 13:16:03 +00:00
|
|
|
procedure SetRepositoryCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
2006-08-26 00:35:42 +00:00
|
|
|
function LoadRepositoryName(
|
|
|
|
const ARepName,ARootAddress : shortstring;
|
|
|
|
out ARepository : PServiceRepository
|
|
|
|
):Integer;
|
|
|
|
procedure ClearRepository(var ARepository : PServiceRepository);
|
2007-03-25 23:47:16 +00:00
|
|
|
procedure SetServiceCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const AServiceName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
2006-08-26 00:35:42 +00:00
|
|
|
procedure SetOperationCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const AServiceName : shortstring;
|
|
|
|
const AOperationName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
|
|
|
//---------------------------------
|
|
|
|
function GetServiceMetadata(const ARepName,AServiceName : shortstring) : PService;
|
|
|
|
procedure ClearServiceMetadata(var AService : PService);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function GetModuleMetadataMngr():IModuleMetadataMngr;
|
|
|
|
|
|
|
|
function LoadRepositoryData(
|
|
|
|
const AStream : TStream;
|
|
|
|
out ARepository : PServiceRepository
|
|
|
|
):LongInt;
|
|
|
|
procedure ClearRepositoryData(var ARepository : PServiceRepository);
|
|
|
|
|
2007-04-02 13:19:48 +00:00
|
|
|
function Find(const AProps : PPropertyData; const APropName : string) : PPropertyData;
|
|
|
|
|
2007-04-26 23:23:41 +00:00
|
|
|
|
|
|
|
function GetServiceDefaultAddress(AServiceTyp : PTypeInfo):string;
|
|
|
|
function GetServiceDefaultFormatProperties(AServiceTyp : PTypeInfo):string;
|
2007-05-02 22:55:35 +00:00
|
|
|
|
2006-08-26 00:35:42 +00:00
|
|
|
implementation
|
2009-12-01 15:50:52 +00:00
|
|
|
uses
|
|
|
|
wst_resources_imp, binary_streamer, imp_utils, wst_types, wst_consts;
|
2007-04-26 23:23:41 +00:00
|
|
|
|
2007-05-02 22:55:35 +00:00
|
|
|
{$INCLUDE wst_rtl_imp.inc}
|
|
|
|
|
2007-04-26 23:23:41 +00:00
|
|
|
const sADDRESS = 'Address';
|
|
|
|
function GetServiceDefaultAddress(AServiceTyp : PTypeInfo):string;
|
|
|
|
var
|
|
|
|
typData : PTypeData;
|
|
|
|
servcMdt : PService;
|
|
|
|
propData : PPropertyData;
|
2010-02-24 16:34:06 +00:00
|
|
|
mmm : IModuleMetadataMngr;
|
2007-04-26 23:23:41 +00:00
|
|
|
begin
|
|
|
|
Result := '';
|
|
|
|
if Assigned(AServiceTyp) and (AServiceTyp^.Kind = tkInterface) then begin
|
|
|
|
typData := GetTypeData(AServiceTyp);
|
|
|
|
if Assigned(typData) then begin
|
2010-02-24 16:34:06 +00:00
|
|
|
mmm := GetModuleMetadataMngr();
|
|
|
|
servcMdt := mmm.GetServiceMetadata(typData^.IntfUnit,AServiceTyp^.Name);
|
|
|
|
if Assigned(servcMdt) then begin
|
|
|
|
try
|
|
|
|
propData := Find(servcMdt^.Properties,sTRANSPORT + '_' + sADDRESS);
|
|
|
|
if Assigned(propData) then
|
|
|
|
Result := propData^.Data;
|
|
|
|
finally
|
|
|
|
mmm.ClearServiceMetadata(servcMdt);
|
|
|
|
end;
|
2007-04-26 23:23:41 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function GetServiceDefaultFormatProperties(AServiceTyp : PTypeInfo):string;
|
|
|
|
var
|
|
|
|
typData : PTypeData;
|
|
|
|
servcMdt : PService;
|
|
|
|
propData : PPropertyData;
|
|
|
|
strName : string;
|
2010-02-24 16:34:06 +00:00
|
|
|
mmm : IModuleMetadataMngr;
|
2007-04-26 23:23:41 +00:00
|
|
|
begin
|
|
|
|
Result := '';
|
|
|
|
if Assigned(AServiceTyp) and (AServiceTyp^.Kind = tkInterface) then begin
|
|
|
|
typData := GetTypeData(AServiceTyp);
|
|
|
|
if Assigned(typData) then begin
|
2010-02-24 16:34:06 +00:00
|
|
|
mmm := GetModuleMetadataMngr();
|
|
|
|
servcMdt := mmm.GetServiceMetadata(typData^.IntfUnit,AServiceTyp^.Name);
|
|
|
|
if Assigned(servcMdt) then begin
|
|
|
|
try
|
|
|
|
propData := servcMdt^.Properties;
|
|
|
|
while Assigned(propData) do begin
|
|
|
|
if ( AnsiPos(sFORMAT + '_',propData^.Name) = 1 ) then begin
|
|
|
|
strName := ExtractOptionName(propData^.Name);
|
|
|
|
if ( Length(strName) > 0 ) then begin
|
|
|
|
Result := Format('%s%s=%s;',[Result,strName,propData^.Data]);
|
|
|
|
end;
|
2007-04-26 23:23:41 +00:00
|
|
|
end;
|
2010-02-24 16:34:06 +00:00
|
|
|
propData := propData^.Next;
|
2007-04-26 23:23:41 +00:00
|
|
|
end;
|
2010-02-24 16:34:06 +00:00
|
|
|
if not IsStrEmpty(Result) then begin
|
|
|
|
Delete(Result,Length(Result),1);
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
mmm.ClearServiceMetadata(servcMdt);
|
2007-04-26 23:23:41 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
2006-08-26 00:35:42 +00:00
|
|
|
|
|
|
|
procedure ClearProperties(var AProps : PPropertyData);
|
|
|
|
var
|
|
|
|
c : Integer;
|
|
|
|
q, p : PPropertyData;
|
|
|
|
begin
|
|
|
|
if not Assigned(AProps) then
|
|
|
|
Exit;
|
2007-05-02 22:55:35 +00:00
|
|
|
c := SizeOf(TPropertyData);
|
2006-08-26 00:35:42 +00:00
|
|
|
p := AProps;
|
|
|
|
while Assigned(p) do begin
|
|
|
|
q := p;
|
|
|
|
p := p^.Next;
|
|
|
|
q^.Name := '';
|
|
|
|
q^.Data := '';
|
|
|
|
Freemem(q,c);
|
|
|
|
end;
|
|
|
|
AProps := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function CloneProperties(const AProps : PPropertyData) : PPropertyData;
|
|
|
|
var
|
|
|
|
c : Integer;
|
|
|
|
p,q, q0 : PPropertyData;
|
|
|
|
begin
|
|
|
|
Result := nil;
|
|
|
|
if not Assigned(AProps) then
|
|
|
|
Exit;
|
2007-05-02 22:55:35 +00:00
|
|
|
c := SizeOf(TPropertyData);
|
|
|
|
q0 := wst_GetMem(c);
|
2006-08-26 00:35:42 +00:00
|
|
|
q := q0;
|
|
|
|
p := AProps;
|
|
|
|
while Assigned(p) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
q^.Next := wst_GetMem(c);
|
2006-08-26 00:35:42 +00:00
|
|
|
FillChar(q^.Next^,c,#0);
|
|
|
|
q := q^.Next;
|
|
|
|
q^.Name := p^.Name;
|
|
|
|
q^.Data := p^.Data;
|
|
|
|
p := p^.Next;
|
|
|
|
end;
|
|
|
|
Result := q0^.Next;
|
|
|
|
Freemem(q0,c);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function Find(const AProps : PPropertyData; const APropName : string) : PPropertyData;
|
|
|
|
begin
|
|
|
|
if Assigned(AProps) then begin
|
|
|
|
Result := AProps;
|
|
|
|
while Assigned(Result) do begin
|
|
|
|
if AnsiSameText(APropName,Result^.Name) then
|
|
|
|
Exit;
|
|
|
|
Result := Result^.Next;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
Result := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function Add(
|
|
|
|
var AProps : PPropertyData;
|
|
|
|
const APropName,
|
|
|
|
APropData : string
|
|
|
|
) : PPropertyData;
|
|
|
|
begin
|
|
|
|
if not Assigned(AProps) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
AProps := wst_GetMem(SizeOf(TPropertyData));
|
|
|
|
FillChar(AProps^,SizeOf(TPropertyData),#0);
|
2006-08-26 00:35:42 +00:00
|
|
|
AProps^.Next := nil;
|
|
|
|
Result := AProps;
|
|
|
|
end else begin
|
|
|
|
Result := Find(AProps,APropName);
|
|
|
|
if not Assigned(Result) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
Result := wst_GetMem(SizeOf(TPropertyData));
|
|
|
|
FillChar(Result^,SizeOf(TPropertyData),#0);
|
2007-04-26 23:23:41 +00:00
|
|
|
Result^.Next := AProps;
|
|
|
|
AProps := Result;
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
Result^.Name := APropName;
|
|
|
|
Result^.Data := APropData;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure ClearService(AService : PService; const AFreeService : Boolean);
|
|
|
|
|
|
|
|
procedure ClearOperation(AOperation : PServiceOperation);
|
|
|
|
var
|
|
|
|
cc : LongInt;
|
|
|
|
begin
|
|
|
|
cc := AOperation^.ParamsCount;
|
|
|
|
if ( cc > 0 ) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
Freemem(AOperation^.Params, cc * SizeOf(TOperationParam) );
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
ClearProperties(AOperation^.Properties);
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
j, k : LongInt;
|
|
|
|
po : PServiceOperation;
|
|
|
|
begin
|
|
|
|
if not Assigned(AService) then
|
|
|
|
Exit;
|
|
|
|
k := AService^.OperationsCount;
|
|
|
|
if ( k > 0 ) then begin
|
|
|
|
po := AService^.Operations;
|
|
|
|
for j := 0 to Pred(k) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
//ClearOperation(@(po[j]));
|
|
|
|
ClearOperation(po);
|
|
|
|
Inc(po);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
2007-05-02 22:55:35 +00:00
|
|
|
Freemem(AService^.Operations, k * SizeOf(TServiceOperation) );
|
2006-08-26 00:35:42 +00:00
|
|
|
AService^.Operations := nil;
|
2009-05-25 16:13:54 +00:00
|
|
|
end;
|
|
|
|
if ( AService^.Properties <> nil ) then begin
|
2007-03-25 23:47:16 +00:00
|
|
|
ClearProperties(AService^.Properties);
|
|
|
|
AService^.Properties := nil;
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
if AFreeService then
|
2007-05-02 22:55:35 +00:00
|
|
|
Freemem(AService,SizeOf(TService));
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure ClearRepositoryData(var ARepository : PServiceRepository);
|
|
|
|
var
|
|
|
|
i, c : LongInt;
|
|
|
|
ps : PService;
|
|
|
|
begin
|
|
|
|
if Assigned(ARepository) then begin
|
|
|
|
c := ARepository^.ServicesCount;
|
|
|
|
if ( c > 0 ) then begin
|
|
|
|
ps := ARepository^.Services;
|
|
|
|
for i := 0 to Pred(c) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
//ClearService(@(ps[i]),false);
|
|
|
|
ClearService(ps,false);
|
|
|
|
Inc(ps);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
2007-05-02 22:55:35 +00:00
|
|
|
Freemem(ARepository^.Services, c * SizeOf(TService) );
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
2015-07-31 13:16:03 +00:00
|
|
|
if (ARepository^.Properties <> nil) then
|
|
|
|
ClearProperties(ARepository^.Properties);
|
2007-05-02 22:55:35 +00:00
|
|
|
Freemem(ARepository,SizeOf(TServiceRepository));
|
2006-08-26 00:35:42 +00:00
|
|
|
ARepository := nil;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function LoadRepositoryData(
|
|
|
|
const AStream : TStream;
|
|
|
|
out ARepository : PServiceRepository
|
|
|
|
):LongInt;
|
|
|
|
var
|
|
|
|
rdr : IDataStoreReader;
|
|
|
|
|
|
|
|
procedure LoadService(AService : PService);
|
|
|
|
|
|
|
|
procedure LoadOperation(AOperation : PServiceOperation);
|
|
|
|
|
|
|
|
procedure LoadParam(APrm : POperationParam);
|
|
|
|
begin
|
2008-09-13 15:19:20 +00:00
|
|
|
APrm^.Name := rdr.ReadAnsiStr();
|
|
|
|
APrm^.TypeName := rdr.ReadAnsiStr();
|
2006-08-26 00:35:42 +00:00
|
|
|
APrm^.Modifier := TOperationParamFlag(rdr.ReadEnum());
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
ii, cc : LongInt;
|
|
|
|
pp : POperationParam;
|
|
|
|
begin
|
2008-09-13 15:19:20 +00:00
|
|
|
AOperation^.Name := rdr.ReadAnsiStr();
|
2006-08-26 00:35:42 +00:00
|
|
|
AOperation^.Properties := nil;
|
|
|
|
cc := rdr.ReadInt8U();
|
|
|
|
if ( cc > 0 ) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
AOperation^.Params := wst_GetMem( cc * SizeOf(TOperationParam) );
|
|
|
|
FillChar(AOperation^.Params^, cc * SizeOf(TOperationParam), #0);
|
2006-08-26 00:35:42 +00:00
|
|
|
AOperation^.ParamsCount := cc;
|
|
|
|
pp := AOperation^.Params;
|
|
|
|
for ii := 0 to Pred(cc) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
//LoadParam(@(pp[ii]));
|
|
|
|
LoadParam(pp);
|
|
|
|
Inc(pp);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
j, k : LongInt;
|
|
|
|
po : PServiceOperation;
|
|
|
|
begin
|
2008-09-13 15:19:20 +00:00
|
|
|
AService^.Name := rdr.ReadAnsiStr();
|
2007-03-25 23:47:16 +00:00
|
|
|
AService^.Properties := nil;
|
2009-12-01 15:50:52 +00:00
|
|
|
k := rdr.ReadInt16U();
|
2006-08-26 00:35:42 +00:00
|
|
|
if ( k > 0 ) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
AService^.Operations := wst_GetMem( k * SizeOf(TServiceOperation) );
|
2006-08-26 00:35:42 +00:00
|
|
|
AService^.OperationsCount := k;
|
2007-05-02 22:55:35 +00:00
|
|
|
FillChar(AService^.Operations^,k * SizeOf(TServiceOperation), #0);
|
2006-08-26 00:35:42 +00:00
|
|
|
po := AService^.Operations;
|
|
|
|
for j := 0 to Pred(k) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
//LoadOperation(@(po[j]));
|
|
|
|
LoadOperation(po);
|
|
|
|
Inc(po);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
buf : string;
|
|
|
|
i, c : LongInt;
|
|
|
|
ps : PService;
|
|
|
|
begin
|
|
|
|
ARepository := nil;
|
|
|
|
rdr := CreateBinaryReader(AStream);
|
2008-09-13 15:19:20 +00:00
|
|
|
buf := rdr.ReadAnsiStr();
|
2006-08-26 00:35:42 +00:00
|
|
|
if ( sWST_SIGNATURE <> buf ) then
|
|
|
|
raise EMetadataException.CreateFmt('Invalid Metadata signature : "%s"',[buf]);
|
2007-05-02 22:55:35 +00:00
|
|
|
c := SizeOf(TServiceRepository);
|
|
|
|
ARepository := wst_GetMem(c);
|
2006-08-26 00:35:42 +00:00
|
|
|
try
|
|
|
|
FillChar(ARepository^,c,#0);
|
2008-09-13 15:19:20 +00:00
|
|
|
ARepository^.Name := rdr.ReadAnsiStr();
|
2009-12-01 15:50:52 +00:00
|
|
|
c := rdr.ReadInt16U();
|
2006-08-26 00:35:42 +00:00
|
|
|
if ( c > 0 ) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
ARepository^.Services := wst_GetMem( c * SizeOf(TService) );
|
2006-08-26 00:35:42 +00:00
|
|
|
ARepository^.ServicesCount := c;
|
2007-05-02 22:55:35 +00:00
|
|
|
FillChar(ARepository^.Services^,c * SizeOf(TService),#0);
|
2006-08-26 00:35:42 +00:00
|
|
|
ps := ARepository^.Services;
|
|
|
|
for i := 0 to Pred(c) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
//LoadService(@(ps[i]));
|
|
|
|
LoadService(ps);
|
|
|
|
Inc(ps);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
except
|
|
|
|
ClearRepositoryData(ARepository);
|
|
|
|
raise;
|
|
|
|
end;
|
2008-07-28 17:41:26 +00:00
|
|
|
Result := c;
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure CopyService(ASrcService,ADestService : PService);
|
|
|
|
|
|
|
|
procedure CopyOperation(ASrcOperation, ADstOperation : PServiceOperation);
|
|
|
|
|
|
|
|
procedure CopyParam(ASrcPrm, ADstPrm : POperationParam);
|
|
|
|
begin
|
|
|
|
ADstPrm^ := ASrcPrm^;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
ii, cc : LongInt;
|
2007-05-02 22:55:35 +00:00
|
|
|
ppSrc, pp : POperationParam;
|
2006-08-26 00:35:42 +00:00
|
|
|
begin
|
|
|
|
ADstOperation^.Name := ASrcOperation^.Name;
|
|
|
|
ADstOperation^.Properties := CloneProperties(ASrcOperation^.Properties);
|
|
|
|
cc := ASrcOperation^.ParamsCount;
|
|
|
|
if ( cc > 0 ) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
ADstOperation^.Params := wst_GetMem( cc * SizeOf(TOperationParam) );
|
|
|
|
FillChar(ADstOperation^.Params^, cc * SizeOf(TOperationParam), #0);
|
2006-08-26 00:35:42 +00:00
|
|
|
ADstOperation^.ParamsCount := cc;
|
2007-05-02 22:55:35 +00:00
|
|
|
ppSrc := ASrcOperation^.Params;
|
2006-08-26 00:35:42 +00:00
|
|
|
pp := ADstOperation^.Params;
|
|
|
|
for ii := 0 to Pred(cc) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
CopyParam(ppSrc,pp);
|
|
|
|
Inc(ppSrc);
|
|
|
|
Inc(pp);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
j, k : LongInt;
|
2007-05-02 22:55:35 +00:00
|
|
|
poSrc, po : PServiceOperation;
|
2006-08-26 00:35:42 +00:00
|
|
|
begin
|
|
|
|
ADestService^.Name := ASrcService^.Name;
|
2007-03-25 23:47:16 +00:00
|
|
|
ADestService^.Properties := CloneProperties(ASrcService^.Properties);
|
2006-08-26 00:35:42 +00:00
|
|
|
k := ASrcService^.OperationsCount;
|
|
|
|
if ( k > 0 ) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
ADestService^.Operations := wst_GetMem( k * SizeOf(TServiceOperation) );
|
2006-08-26 00:35:42 +00:00
|
|
|
ADestService^.OperationsCount := k;
|
2007-05-02 22:55:35 +00:00
|
|
|
FillChar(ADestService^.Operations^,k * SizeOf(TServiceOperation), #0);
|
2006-08-26 00:35:42 +00:00
|
|
|
po := ADestService^.Operations;
|
2007-05-02 22:55:35 +00:00
|
|
|
poSrc := ASrcService^.Operations;
|
2006-08-26 00:35:42 +00:00
|
|
|
for j := 0 to Pred(k) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
CopyOperation(poSrc,po);
|
|
|
|
Inc(poSrc);
|
|
|
|
Inc(po);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function CloneService(const ASrcService : PService) : PService;
|
|
|
|
var
|
|
|
|
c : Integer;
|
|
|
|
begin
|
2007-05-02 22:55:35 +00:00
|
|
|
c := SizeOf(TService);
|
|
|
|
Result := wst_GetMem(c);
|
2006-08-26 00:35:42 +00:00
|
|
|
FillChar(Result^,c,#0);
|
|
|
|
CopyService(ASrcService,Result);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure CloneRepository(
|
|
|
|
const ASource : PServiceRepository;
|
|
|
|
out ADest : PServiceRepository
|
|
|
|
);
|
|
|
|
var
|
|
|
|
i, c : LongInt;
|
2007-05-02 22:55:35 +00:00
|
|
|
psSrc, ps : PService;
|
2006-08-26 00:35:42 +00:00
|
|
|
begin
|
|
|
|
ADest := nil;
|
|
|
|
if not Assigned(ASource) then
|
|
|
|
Exit;
|
2007-05-02 22:55:35 +00:00
|
|
|
c := SizeOf(TServiceRepository);
|
|
|
|
ADest := wst_GetMem(c);
|
2006-08-26 00:35:42 +00:00
|
|
|
try
|
|
|
|
FillChar(ADest^,c,#0);
|
|
|
|
ADest^.Name := ASource^.Name;
|
|
|
|
ADest^.NameSpace := ASource^.NameSpace;
|
|
|
|
ADest^.RootAddress := ASource^.RootAddress;
|
2015-07-31 13:16:03 +00:00
|
|
|
ADest^.Properties := CloneProperties(ASource^.Properties);
|
2006-08-26 00:35:42 +00:00
|
|
|
c := ASource^.ServicesCount;
|
|
|
|
if ( c > 0 ) then begin
|
2007-05-02 22:55:35 +00:00
|
|
|
ADest^.Services := wst_GetMem( c * SizeOf(TService) );
|
2006-08-26 00:35:42 +00:00
|
|
|
ADest^.ServicesCount := c;
|
2007-05-02 22:55:35 +00:00
|
|
|
FillChar(ADest^.Services^,c * SizeOf(TService),#0);
|
2006-08-26 00:35:42 +00:00
|
|
|
ps := ADest^.Services;
|
2007-05-02 22:55:35 +00:00
|
|
|
psSrc := ASource^.Services;
|
2006-08-26 00:35:42 +00:00
|
|
|
for i := 0 to Pred(c) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
CopyService(psSrc,ps);
|
2015-06-13 10:44:35 +00:00
|
|
|
Inc(psSrc);
|
|
|
|
Inc(ps);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
except
|
|
|
|
ClearRepositoryData(ADest);
|
|
|
|
raise;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
{ TModuleMetadataMngr }
|
|
|
|
|
2015-01-19 09:31:59 +00:00
|
|
|
TModuleMetadataMngr = class(TInterfacedObject,IModuleMetadataMngr)
|
2006-08-26 00:35:42 +00:00
|
|
|
private
|
|
|
|
FList : TStringList;
|
|
|
|
FRepositories : array of PServiceRepository;
|
|
|
|
private
|
|
|
|
procedure LoadRegisteredNames();
|
|
|
|
procedure ClearList();
|
|
|
|
function FindInnerListIndex(const ARepName : shortstring):Integer;
|
|
|
|
function InternalLoadRepository(const ARepName : shortstring):Integer;
|
|
|
|
protected
|
|
|
|
function IndexOfName(const ARepName : shortstring):Integer;
|
|
|
|
procedure RegisterRepository(const ARepName : shortstring);
|
|
|
|
function GetCount():Integer;
|
|
|
|
function GetRepositoryName(const AIndex : Integer):shortstring;
|
|
|
|
procedure SetRepositoryNameSpace(const ARepName,ANameSpace : shortstring);
|
2015-07-31 13:16:03 +00:00
|
|
|
procedure SetRepositoryCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
2006-08-26 00:35:42 +00:00
|
|
|
function LoadRepositoryName(
|
|
|
|
const ARepName,ARootAddress : shortstring;
|
|
|
|
out ARepository : PServiceRepository
|
|
|
|
):Integer;
|
|
|
|
procedure ClearRepository(var ARepository : PServiceRepository);
|
2007-03-25 23:47:16 +00:00
|
|
|
procedure SetServiceCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const AServiceName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
2006-08-26 00:35:42 +00:00
|
|
|
procedure SetOperationCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const AServiceName : shortstring;
|
|
|
|
const AOperationName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
|
|
|
function GetServiceMetadata(const ARepName,AServiceName : shortstring) : PService;
|
|
|
|
procedure ClearServiceMetadata(var AService : PService);
|
|
|
|
public
|
|
|
|
constructor Create();
|
|
|
|
destructor Destroy();override;
|
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
ModuleMetadataMngrInst : IModuleMetadataMngr = nil;
|
|
|
|
|
|
|
|
function GetModuleMetadataMngr():IModuleMetadataMngr;
|
|
|
|
begin
|
|
|
|
if not Assigned(ModuleMetadataMngrInst) then
|
2015-01-19 09:31:59 +00:00
|
|
|
ModuleMetadataMngrInst := TModuleMetadataMngr.Create();
|
2006-08-26 00:35:42 +00:00
|
|
|
Result := ModuleMetadataMngrInst;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ TModuleMetadataMngr }
|
|
|
|
|
|
|
|
procedure TModuleMetadataMngr.LoadRegisteredNames();
|
2006-11-12 13:31:22 +00:00
|
|
|
|
2006-08-26 00:35:42 +00:00
|
|
|
var
|
2006-11-12 13:31:22 +00:00
|
|
|
i : Integer;
|
|
|
|
L : TStrings;
|
|
|
|
|
2006-08-26 00:35:42 +00:00
|
|
|
begin
|
2006-11-12 13:31:22 +00:00
|
|
|
L:=TStringList.Create;
|
|
|
|
Try
|
|
|
|
GetWSTResourceManager.GetResourceList(L);
|
|
|
|
For I:=0 to L.Count-1 do
|
|
|
|
RegisterRepository(L[i]);
|
|
|
|
finally
|
|
|
|
L.Free;
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TModuleMetadataMngr.ClearList();
|
|
|
|
var
|
|
|
|
i : Integer;
|
|
|
|
begin
|
|
|
|
for i := 0 to Length(FRepositories) - 1 do begin
|
|
|
|
ClearRepository(FRepositories[i]);
|
|
|
|
end;
|
|
|
|
SetLength(FRepositories,0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TModuleMetadataMngr.FindInnerListIndex(const ARepName: shortstring): Integer;
|
|
|
|
begin
|
|
|
|
for Result := 0 to Pred(Length(FRepositories)) do begin
|
|
|
|
if AnsiSameText(ARepName,FRepositories[Result]^.Name) then
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
Result := -1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TModuleMetadataMngr.InternalLoadRepository(const ARepName: shortstring): Integer;
|
|
|
|
var
|
|
|
|
tmpStrm : TMemoryStream;
|
2008-12-17 21:29:09 +00:00
|
|
|
strBuffer : TBinaryString;
|
2006-08-26 00:35:42 +00:00
|
|
|
i : Integer;
|
|
|
|
tmpRes : PServiceRepository;
|
2006-11-12 13:31:22 +00:00
|
|
|
|
2006-08-26 00:35:42 +00:00
|
|
|
begin
|
2006-11-12 13:31:22 +00:00
|
|
|
If not GetWSTResourceManager.HasResource(ARepName) then
|
2006-08-26 00:35:42 +00:00
|
|
|
raise EMetadataException.CreateFmt('Repository not registered : "%s"',[ARepName]);
|
|
|
|
Result := FindInnerListIndex(ARepName);
|
|
|
|
if ( Result < 0 ) then begin
|
|
|
|
tmpStrm := TMemoryStream.Create();
|
|
|
|
try
|
2006-11-12 13:31:22 +00:00
|
|
|
strBuffer := GetWSTResourceManager.ResourceAsString(ARepName);
|
2006-08-26 00:35:42 +00:00
|
|
|
i := Length(strBuffer);
|
|
|
|
tmpStrm.Write(strBuffer[1],i);
|
|
|
|
tmpStrm.Position := 0;
|
|
|
|
LoadRepositoryData(tmpStrm,tmpRes);
|
|
|
|
if Assigned(tmpRes) then begin
|
|
|
|
Result := Length(FRepositories);
|
|
|
|
SetLength(FRepositories, ( Result + 1 ) );
|
|
|
|
FRepositories[Result] := tmpRes;
|
|
|
|
i := Length(tmpRes^.RootAddress);
|
|
|
|
if ( i = 0 ) or ( tmpRes^.RootAddress[i] <> '/' ) then
|
|
|
|
tmpRes^.RootAddress := tmpRes^.RootAddress + '/';
|
|
|
|
tmpRes^.RootAddress := tmpRes^.RootAddress + 'services/';
|
|
|
|
tmpRes^.NameSpace := FList.Values[tmpRes^.Name];
|
|
|
|
if ( Length(tmpRes^.NameSpace) = 0 ) then
|
|
|
|
tmpRes^.NameSpace := 'urn:' + tmpRes^.Name;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
tmpStrm.Free();
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TModuleMetadataMngr.IndexOfName(const ARepName: shortstring): Integer;
|
|
|
|
begin
|
|
|
|
Result := FList.IndexOfName(ARepName);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TModuleMetadataMngr.RegisterRepository(const ARepName: shortstring);
|
|
|
|
begin
|
|
|
|
if ( FList.IndexOfName(ARepName) = -1 ) then begin
|
|
|
|
FList.Values[ARepName] := 'urn:' + ARepName;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TModuleMetadataMngr.GetCount(): Integer;
|
|
|
|
begin
|
|
|
|
Result := FList.Count;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TModuleMetadataMngr.GetRepositoryName(const AIndex: Integer): shortstring;
|
|
|
|
begin
|
|
|
|
Result := FList.Names[AIndex];
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TModuleMetadataMngr.SetRepositoryNameSpace(const ARepName,ANameSpace: shortstring);
|
|
|
|
var
|
|
|
|
i : Integer;
|
|
|
|
begin
|
|
|
|
FList.Values[ARepName] := ANameSpace;
|
|
|
|
i := FindInnerListIndex(ARepName);
|
|
|
|
if ( i >= 0 ) then
|
|
|
|
FRepositories[i]^.NameSpace := ANameSpace;
|
|
|
|
end;
|
|
|
|
|
2015-07-31 13:16:03 +00:00
|
|
|
procedure TModuleMetadataMngr.SetRepositoryCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
|
|
|
var
|
|
|
|
i : Integer;
|
|
|
|
rp : PServiceRepository;
|
|
|
|
sp : PService;
|
|
|
|
begin
|
|
|
|
i := FindInnerListIndex(ARepName);
|
|
|
|
if (i < 0) then
|
|
|
|
i := InternalLoadRepository(ARepName);
|
|
|
|
rp := FRepositories[i];
|
|
|
|
Add(rp^.Properties,ADataName,AData);
|
|
|
|
end;
|
|
|
|
|
2006-08-26 00:35:42 +00:00
|
|
|
function TModuleMetadataMngr.LoadRepositoryName(
|
|
|
|
const ARepName,ARootAddress : shortstring;
|
|
|
|
out ARepository : PServiceRepository
|
|
|
|
): Integer;
|
|
|
|
var
|
|
|
|
strBuffer : string;
|
|
|
|
i : Integer;
|
|
|
|
begin
|
|
|
|
Result := 0;
|
|
|
|
ARepository := nil;
|
|
|
|
i := FindInnerListIndex(ARepName);
|
|
|
|
if ( i < 0 ) then begin
|
|
|
|
i := InternalLoadRepository(ARepName);
|
|
|
|
end;
|
|
|
|
if ( Length(ARootAddress) > 0 ) and ( AnsiPos(ARootAddress,FRepositories[i]^.RootAddress) <> 1 ) then begin
|
|
|
|
strBuffer := ARootAddress;
|
|
|
|
if ( strBuffer[Length(strBuffer)] = '/' ) then
|
|
|
|
Delete(strBuffer,Length(strBuffer),1);
|
|
|
|
FRepositories[i]^.RootAddress := strBuffer + FRepositories[i]^.RootAddress;
|
|
|
|
end;
|
|
|
|
if ( i >= 0 ) then begin
|
|
|
|
CloneRepository(FRepositories[i],ARepository);
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TModuleMetadataMngr.ClearRepository(var ARepository: PServiceRepository);
|
|
|
|
begin
|
|
|
|
ClearRepositoryData(ARepository);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function FindService(
|
|
|
|
const ARep : PServiceRepository;
|
|
|
|
const AServiceName : shortstring
|
|
|
|
) : PService;
|
|
|
|
var
|
|
|
|
i : Integer;
|
2007-05-02 22:55:35 +00:00
|
|
|
srv : PService;
|
2006-08-26 00:35:42 +00:00
|
|
|
begin
|
2007-05-02 22:55:35 +00:00
|
|
|
srv := ARep^.Services;
|
2006-08-26 00:35:42 +00:00
|
|
|
for i := 0 to Pred(ARep^.ServicesCount) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
//if AnsiSameText(AServiceName,ARep^.Services[i].Name) then begin
|
|
|
|
if AnsiSameText(AServiceName,srv^.Name) then begin
|
|
|
|
Result := srv;
|
2006-08-26 00:35:42 +00:00
|
|
|
Exit;
|
|
|
|
end;
|
2007-05-02 22:55:35 +00:00
|
|
|
Inc(srv);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
Result := nil;
|
|
|
|
end;
|
|
|
|
|
2007-03-25 23:47:16 +00:00
|
|
|
procedure TModuleMetadataMngr.SetServiceCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const AServiceName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
|
|
|
var
|
|
|
|
i : Integer;
|
|
|
|
rp : PServiceRepository;
|
|
|
|
sp : PService;
|
|
|
|
begin
|
|
|
|
i := FindInnerListIndex(ARepName);
|
|
|
|
if ( i < 0 ) then
|
|
|
|
i := InternalLoadRepository(ARepName);
|
|
|
|
rp := FRepositories[i];
|
|
|
|
sp := FindService(rp,AServiceName);
|
|
|
|
if not Assigned(sp) then
|
|
|
|
raise EMetadataException.CreateFmt('Service non found : "%s"',[AServiceName]);
|
|
|
|
Add(sp^.Properties,ADataName,AData);
|
|
|
|
end;
|
|
|
|
|
2006-08-26 00:35:42 +00:00
|
|
|
function FindOperation(
|
|
|
|
const AServ : PService;
|
|
|
|
const AOperationName : shortstring
|
|
|
|
) : PServiceOperation;
|
|
|
|
var
|
|
|
|
i : Integer;
|
2007-05-02 22:55:35 +00:00
|
|
|
sop : PServiceOperation;
|
2006-08-26 00:35:42 +00:00
|
|
|
begin
|
2007-05-02 22:55:35 +00:00
|
|
|
sop := AServ^.Operations;
|
2006-08-26 00:35:42 +00:00
|
|
|
for i := 0 to Pred(AServ^.OperationsCount) do begin
|
2007-05-02 22:55:35 +00:00
|
|
|
if AnsiSameText(AOperationName,sop^.Name) then begin
|
|
|
|
Result := sop;
|
2006-08-26 00:35:42 +00:00
|
|
|
Exit;
|
|
|
|
end;
|
2007-05-02 22:55:35 +00:00
|
|
|
Inc(sop);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
Result := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TModuleMetadataMngr.SetOperationCustomData(
|
|
|
|
const ARepName : shortstring;
|
|
|
|
const AServiceName : shortstring;
|
|
|
|
const AOperationName : shortstring;
|
|
|
|
const ADataName,
|
|
|
|
AData : string
|
|
|
|
);
|
|
|
|
var
|
|
|
|
i : Integer;
|
|
|
|
rp : PServiceRepository;
|
|
|
|
sp : PService;
|
|
|
|
sop : PServiceOperation;
|
|
|
|
begin
|
|
|
|
i := FindInnerListIndex(ARepName);
|
|
|
|
if ( i < 0 ) then
|
|
|
|
i := InternalLoadRepository(ARepName);
|
|
|
|
rp := FRepositories[i];
|
|
|
|
sp := FindService(rp,AServiceName);
|
|
|
|
if not Assigned(sp) then
|
|
|
|
raise EMetadataException.CreateFmt('Service non found : "%s"',[AServiceName]);
|
|
|
|
sop := FindOperation(sp,AOperationName);
|
|
|
|
if not Assigned(sop) then
|
|
|
|
raise EMetadataException.CreateFmt('Operation non found : "%s"',[AOperationName]);
|
|
|
|
Add(sop^.Properties,ADataName,AData);
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TModuleMetadataMngr.GetServiceMetadata(const ARepName,AServiceName: shortstring): PService;
|
|
|
|
var
|
|
|
|
i : Integer;
|
|
|
|
rp : PServiceRepository;
|
|
|
|
begin
|
|
|
|
i := FindInnerListIndex(ARepName);
|
|
|
|
if ( i < 0 ) then
|
|
|
|
i := InternalLoadRepository(ARepName);
|
|
|
|
rp := FRepositories[i];
|
2007-05-02 22:55:35 +00:00
|
|
|
Result := FindService(rp,AServiceName);
|
|
|
|
if ( Result <> nil ) then begin
|
|
|
|
Result := CloneService(Result);
|
2006-08-26 00:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TModuleMetadataMngr.ClearServiceMetadata(var AService: PService);
|
|
|
|
begin
|
|
|
|
ClearService(AService,True);
|
|
|
|
AService := nil;
|
|
|
|
end;
|
|
|
|
|
|
|
|
constructor TModuleMetadataMngr.Create();
|
|
|
|
begin
|
|
|
|
inherited Create();
|
|
|
|
FRepositories := nil;
|
|
|
|
FList := TStringList.Create();
|
|
|
|
LoadRegisteredNames();
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TModuleMetadataMngr.Destroy();
|
|
|
|
begin
|
|
|
|
ClearList();
|
|
|
|
FreeAndNil(FList);
|
|
|
|
inherited Destroy();
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
initialization
|
|
|
|
|
|
|
|
finalization
|
|
|
|
ModuleMetadataMngrInst := nil;
|
|
|
|
|
|
|
|
End.
|