- Recompilación en Delphi10 de todos los paquetes de RO para generar las DCU's en Lib\D10 - Recompilación en Delphi10 de todos los paquetes de DA para generar las DCU's en Lib\D10 git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@9 b6239004-a887-0f4b-9937-50029ccdca16
663 lines
24 KiB
ObjectPascal
663 lines
24 KiB
ObjectPascal
unit uRODLToWSDL;
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ 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. }
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{$IFDEF LINUX}
|
|
{$I ../RemObjects.inc}
|
|
{$ELSE}
|
|
{$I ..\RemObjects.inc}
|
|
{$ENDIF LINUX}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF REMOBJECTS_TRIAL}uROTrial,{$ENDIF}
|
|
Classes, uRODL, uROTypes, uROXMLSerializer;
|
|
|
|
const
|
|
|
|
SOAPDataTypes : array[TRODataType] of string = (
|
|
'int',
|
|
'dateTime',
|
|
'double',
|
|
'double',
|
|
'string',
|
|
'string',
|
|
'long',
|
|
'boolean',
|
|
'anyType',
|
|
dts_base64Binary,
|
|
'any',
|
|
'string',
|
|
'decimal',
|
|
'???');
|
|
|
|
|
|
type
|
|
{ TRODLToWSDL }
|
|
TRODLToWSDL = class(TRODLConverter)
|
|
private
|
|
fLocation: string;
|
|
fShowClientId: Boolean;
|
|
fUseLiteral: Boolean;
|
|
fUseDocument: Boolean;
|
|
fTargetNamespace: string;
|
|
fExternalTypesAsReferences: Boolean;
|
|
fExternalRefs, // namespace
|
|
fExternalUrls: TStrings; // uri
|
|
procedure SetLocation(const Value: string);
|
|
|
|
procedure WriteEnum(anEnum : TRODLEnum);
|
|
procedure WriteStruct(const aLibrary: TRODLLibrary; aStruct : TRODLStruct);
|
|
procedure WriteArray(anArray : TRODLArray);
|
|
|
|
procedure WriteMessages(aLibrary: TRODLLibrary; aService : TRODLService);
|
|
procedure WriteLiteralParameters(aLibrary: TRODLLibrary; aService : TRODLService);
|
|
procedure WriteBindings(aLibrary: TRODLLibrary; aService : TRODLService);
|
|
procedure WritePorts(aLibrary: TRODLLibrary; aService : TRODLService);
|
|
procedure WriteService(aLibrary: TRODLLibrary; aService : TRODLService);
|
|
function GetAnchestor(aLibrary: TRODLLibrary;
|
|
aService: TRODLService): TRODLService;
|
|
procedure WriteAnnotation(aDocString: string; aIndentation: Integer = 0; aNs:
|
|
string = 'xs:');
|
|
procedure WriteDocumentation(aDocString: string; aIndentation: Integer = 0;
|
|
aNs: string = 'xs:');
|
|
function ExtSOAPDataType(aLibrary: TRODLLibrary; const aDataTypeName : string) : string;
|
|
protected
|
|
procedure IntConvert(const aLibrary : TRODLLibrary; const aTargetEntity : string = ''); override;
|
|
procedure AddExternal(aNode: TRODLEntity);
|
|
|
|
public
|
|
constructor Create(const aLibraryFile: string; const aTargetEntity: string = ''); overload; override;
|
|
constructor Create(const aLibrary: TRODLLibrary; const aTargetEntity: string = ''); overload; override;
|
|
destructor Destroy; override;
|
|
property Location : string read fLocation write SetLocation;
|
|
property TargetNamespace: string read fTargetNamespace write fTargetNamespace;
|
|
property ShowClientId : Boolean read fShowClientId write fShowClientId;
|
|
property UseLiteral : Boolean read fUseLiteral write fUseLiteral;
|
|
property UseDocument : Boolean read fUseDocument write fUseDocument;
|
|
property ExternalTypesAsReferences : Boolean read fExternalTypesAsReferences write fExternalTypesAsReferences;
|
|
end;
|
|
|
|
function SOAPDataType(const aDataTypeName : string; IncludeNamespace : boolean = TRUE) : string;
|
|
|
|
implementation
|
|
|
|
uses SysUtils;
|
|
|
|
function SOAPDataType(const aDataTypeName : string; IncludeNamespace : boolean = TRUE) : string;
|
|
var dt : TRODataType;
|
|
begin
|
|
dt := StrToDataType(aDataTypeName);
|
|
if (dt=rtUserDefined)
|
|
then result := aDataTypeName
|
|
else result := SOAPDataTypes[dt];
|
|
|
|
if IncludeNamespace then begin
|
|
if (dt=rtUserDefined) then result := ns_Custom+':'+result
|
|
else result := ns_Standard+':'+result;
|
|
end;
|
|
end;
|
|
|
|
{ TRODLToWSDL }
|
|
|
|
const
|
|
definitions_ns : array[0..6] of string = ('xmlns="http://schemas.xmlsoap.org/wsdl/" ',
|
|
'xmlns:xs="http://www.w3.org/2001/XMLSchema" ',
|
|
'name="%s" ',
|
|
'xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" ',
|
|
'xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" ',
|
|
'xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" ',
|
|
'xmlns:'+ns_Custom+'="urn:%s"');
|
|
|
|
procedure TRODLToWSDL.IntConvert(const aLibrary: TRODLLibrary; const aTargetEntity: string);
|
|
var
|
|
s, i: integer;
|
|
lService: TRODLService;
|
|
begin
|
|
with aLibrary do begin
|
|
if (aTargetEntity<>'') then begin
|
|
lService := aLibrary.FindService(aTargetEntity);
|
|
if (lService <> nil) then
|
|
if lService.isPrivate then Exit;
|
|
end else
|
|
lService := NIL;
|
|
|
|
Write('<?xml version="1.0" encoding="UTF-8" ?>');
|
|
Write('<definitions ');
|
|
|
|
for i := 0 to High(definitions_ns) do
|
|
Write(Format(definitions_ns[i], [Name]), 3);
|
|
|
|
Write('targetNamespace="'+ fTargetNamespace +'" ', 3);
|
|
Write('xmlns:tns="'+ fTargetNamespace +'" ', 3);
|
|
|
|
fExternalRefs.Clear;
|
|
if fExternalTypesAsReferences then begin
|
|
for i := 0 to EnumCount -1 do
|
|
AddExternal(Enums[i]);
|
|
for i := 0 to StructCount -1 do
|
|
AddExternal(Structs[i]);
|
|
for i := 0 to ARrayCount -1 do
|
|
AddExternal(Arrays[i]);
|
|
end;
|
|
|
|
for i := 0 to fExternalRefs.Count -1 do begin
|
|
write('xmlns:ns'+IntToStr(i)+'="'+fExternalRefs[i]+'" ', 3);
|
|
end;
|
|
|
|
Write('>');
|
|
WriteAnnotation(aLibrary.Documentation); {Giovanni}
|
|
|
|
|
|
// Write types
|
|
|
|
Write('<types>', 3);
|
|
Write(Format('<xs:schema targetNamespace="urn:%s" xmlns="urn:%s" elementFormDefault="qualified">', [Name, Name]), 6);
|
|
|
|
for i := 0 to fExternalRefs.Count -1 do begin
|
|
Write(Format('<xsd:include namespace="%s" schemaLocation="%s" />',[fExternalRefs[i], fExternalUrls[i]] ), 3);
|
|
end;
|
|
|
|
for i := 0 to (EnumCount-1) do WriteEnum(Enums[i]);
|
|
for i := 0 to (StructCount-1) do WriteStruct(aLibrary, Structs[i]);
|
|
for i := 0 to (ArrayCount-1) do WriteArray(Arrays[i]);
|
|
if fUseLiteral and fUseDocument then begin
|
|
if (aTargetEntity<>'') then WriteLiteralParameters(aLibrary, lService)
|
|
else for s := 0 to (ServiceCount-1) do begin
|
|
lService := Services[s];
|
|
WriteLiteralParameters(aLibrary, lService);
|
|
end;
|
|
if fShowClientId then begin
|
|
Write('<xs:element name="ROClientIDHeader">', 3);
|
|
Write('<xs:complexType>', 6);
|
|
Write('<xs:sequence>', 9);
|
|
Write('<xs:element name="ID" minOccurs="0" maxOccurs="1" type="xs:string" />', 6);
|
|
Write('</xs:sequence>', 9);
|
|
Write('</xs:complexType>', 6);
|
|
Write('</xs:element>', 3);
|
|
end;
|
|
end;
|
|
Write('</xs:schema>', 6);
|
|
Write('</types>', 3);
|
|
|
|
// Writes messages
|
|
if (aTargetEntity<>'') then WriteMessages(aLibrary, lService)
|
|
else for s := 0 to (ServiceCount-1) do begin
|
|
lService := Services[s];
|
|
WriteMessages(aLibrary, lService);
|
|
end;
|
|
if fShowClientId and fUseLiteral and fUseDocument then begin
|
|
Write('<message name="ROClientIDHeaderMessage">', 3);
|
|
Write('<part name="ROClientID" element="ro:ROClientIDHeader" />', 3);
|
|
Write('</message>', 3);
|
|
end;
|
|
|
|
// Writes port and operations
|
|
if (aTargetEntity<>'') then WritePorts(aLibrary, lService)
|
|
else for s := 0 to (ServiceCount-1) do begin
|
|
lService := Services[s];
|
|
WritePorts(aLibrary, lService);
|
|
end;
|
|
|
|
// Write bindings
|
|
if (aTargetEntity<>'') then WriteBindings(aLibrary, lService)
|
|
else for s := 0 to (ServiceCount-1) do begin
|
|
lService := Services[s];
|
|
WriteBindings(aLibrary, lService);
|
|
end;
|
|
|
|
// Writes services
|
|
if (aTargetEntity<>'') then WriteService(aLibrary, lService)
|
|
else for s := 0 to (ServiceCount-1) do begin
|
|
lService := Services[s];
|
|
WriteService(aLibrary, lService);
|
|
end;
|
|
|
|
Write('</definitions>');
|
|
end;
|
|
end;
|
|
|
|
procedure TRODLToWSDL.SetLocation(const Value: string);
|
|
begin
|
|
fLocation := Value;
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WriteArray(anArray: TRODLArray);
|
|
var
|
|
lMin,
|
|
lMax: Integer;
|
|
begin
|
|
if fExternalTypesAsReferences and (anArray.Attributes.Values['ImportedFromUrl'] <> '') then exit;
|
|
Write(Format('<xs:complexType name="%s">', [anArray.Name]), 9);
|
|
WriteAnnotation(anArray.Documentation, 9);
|
|
|
|
if fUseDocument then begin
|
|
Write('<xs:sequence>', 12);
|
|
|
|
lMax := StrToIntDef(anArray.Attributes.Values['MaxOccurs'], -1);
|
|
lMin := StrToIntDef(anArray.Attributes.Values['MinOccurs'], 0);
|
|
|
|
if lMax = -1 then begin
|
|
Write(Format('<xs:element name="%s" minOccurs="%d" maxOccurs="unbounded" type="%s" />', [SOAPDataType(anArray.ElementType, false),
|
|
lMin,
|
|
ExtSOAPDataType(anArray.OwnerLibrary, anArray.ElementType)]), 15);
|
|
end else begin
|
|
Write(Format('<xs:element name="%s" minOccurs="%d" maxOccurs="%d" type="%s" />', [SOAPDataType(anArray.ElementType, false),
|
|
lMin,
|
|
lMax,
|
|
ExtSOAPDataType(anArray.OwnerLibrary, anArray.ElementType)]), 15);
|
|
end;
|
|
Write('</xs:sequence>', 12);
|
|
end else begin
|
|
Write('<xs:complexContent>', 12);
|
|
Write('<xs:restriction base="soapenc:Array">', 15);
|
|
Write('<xs:sequence />', 18);
|
|
Write(Format('<xs:attribute ref="soapenc:arrayType" n1:arrayType="%s[]" xmlns:n1="http://schemas.xmlsoap.org/wsdl/" />',
|
|
[ExtSOAPDataType(anArray.OwnerLibrary, anArray.ElementType)]), 18);
|
|
Write('</xs:restriction>', 15);
|
|
|
|
Write('</xs:complexContent>', 12);
|
|
|
|
end;
|
|
Write('</xs:complexType>', 9);
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WriteEnum(anEnum: TRODLEnum);
|
|
var i : integer;
|
|
begin
|
|
if fExternalTypesAsReferences and (anEnum.Attributes.Values['ImportedFromUrl'] <> '') then exit;
|
|
Write(Format('<xs:simpleType name="%s">', [anEnum.Name]), 9);
|
|
WriteAnnotation(anEnum.Documentation, 12); {Giovanni}
|
|
Write('<xs:restriction base="xs:string">', 12);
|
|
for i := 0 to anEnum.Count-1 do
|
|
begin
|
|
//WriteDocumentation(anEnum.Items[i].Documentation, 12); {Giovanni}
|
|
Write(Format('<xs:enumeration value="%s" />', [anEnum.Items[i].Name]), 15);
|
|
end;
|
|
Write('</xs:restriction>', 12);
|
|
Write('</xs:simpleType>', 9);
|
|
end;
|
|
|
|
function TRODLToWSDL.GetAnchestor(aLibrary: TRODLLibrary; aService: TRODLService): TRODLService;
|
|
begin
|
|
result := NIL;
|
|
if (aService.Ancestor<>'') and not aService.isPrivate
|
|
then result := aLibrary.FindService(aService.Ancestor)
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WriteMessages(aLibrary: TRODLLibrary; aService: TRODLService);
|
|
var o, p : integer;
|
|
dups : TStringList;
|
|
s, svcname, mtdname : string;
|
|
op : TRODLOperation;
|
|
begin
|
|
// Writes all the methods of this service and its anchestors.
|
|
// If more than one service descend from the same base one, the WSDL has to be generated
|
|
// using a format like this: http://localhost:8099/SOAP?Service=ServiceOne
|
|
|
|
svcname := aService.Name;
|
|
dups := TStringList.Create;
|
|
dups.Duplicates := dupIgnore;
|
|
dups.Sorted := TRUE;
|
|
try
|
|
while Assigned(aService) and not aService.isPrivate do begin
|
|
|
|
with aService.Default do begin
|
|
for o := 0 to (Count-1) do begin
|
|
op := Items[o];
|
|
|
|
// If a method with this name is present, it skips it
|
|
mtdname := UpperCase(op.Name);
|
|
if (dups.IndexOf(mtdname)>=0) then Continue else dups.Add(mtdname);
|
|
|
|
if fUseLiteral and fUseDocument then begin
|
|
Write(Format('<message name="%s___%sRequest">', [svcname, op.Name]), 3);
|
|
s := op.Attributes.Values['SOAPInputName'];
|
|
if s = '' then s := Format('%s___%s', [svcname, op.Name]);
|
|
Write(Format('<part name="parameters" element="ro:%s" />', [s]), 6);
|
|
Write('</message>', 3);
|
|
Write(Format('<message name="%s___%sResponse">', [svcname, op.Name]), 3);
|
|
s := op.Attributes.Values['SOAPOutputName'];
|
|
if s = '' then s := Format('%s___%sResponse', [svcname, op.Name]);
|
|
Write(Format('<part name="parameters" element="ro:%s" />', [s]), 6);
|
|
Write('</message>', 3);
|
|
end
|
|
else begin
|
|
// Continues
|
|
with Items[o] do begin
|
|
// Request
|
|
Write(Format('<message name="%s___%sRequest">', [svcname, op.Name]), 3);
|
|
for p := 0 to (Count-1) do
|
|
if IsInputFlag(Items[p].Flag) then
|
|
Write(Format('<part name="%s" type="%s" />', [Items[p].Name, ExtSOAPDataType(aLibrary, Items[p].DataType)]), 6);
|
|
Write('</message>', 3);
|
|
|
|
// Response
|
|
Write(Format('<message name="%s___%sResponse">', [svcname, op.Name]), 3);
|
|
|
|
if Assigned(aService.Default.Items[o].Result) then
|
|
Write(Format('<part name="%s" type="%s" />', [op.Result.Name, ExtSOAPDataType(aLibrary, op.Result.DataType)]), 6);
|
|
//Write(Format('<part name="return" type="%s" />', [SOAPDataType(aService.Default.Items[o].Result.DataType)]), 6);
|
|
|
|
for p := 0 to (Count-1) do begin
|
|
if IsOutputFlag(Items[p].Flag) then
|
|
Write(Format('<part name="%s" type="%s" />', [Items[p].Name, ExtSOAPDataType(aLibrary, Items[p].DataType)]), 6);
|
|
end;
|
|
Write('</message>', 3);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
aService := GetAnchestor(aLibrary, aService);
|
|
end;
|
|
finally
|
|
dups.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WritePorts(aLibrary: TRODLLibrary; aService: TRODLService);
|
|
var o : integer;
|
|
svcname: string;
|
|
begin
|
|
// Writes a port for each method of this service and its anchestors.
|
|
// Refer to the comment in TRODLToWSDL.WriteMessages
|
|
if aService.isPrivate then Exit;
|
|
svcname := aService.Name;
|
|
Write(Format('<portType name="%s">', [svcname]), 3);
|
|
WriteDocumentation(aService.Documentation, 6,'');
|
|
while Assigned(aService) and not aService.isPrivate do begin
|
|
|
|
for o := 0 to (aService.Default.Count-1) do begin
|
|
with aService.Default.Items[o] do begin
|
|
Write(Format('<operation name="%s">', [Name]), 6);
|
|
WriteDocumentation(Documentation, 6,''); {Giovanni}
|
|
Write(Format('<input message="tns:%s___%sRequest" />', [svcname, Name]), 9);
|
|
Write(Format('<output message="tns:%s___%sResponse" />', [svcname, Name]), 9);
|
|
Write(Format('</operation>', [Name]), 6)
|
|
end;
|
|
end;
|
|
|
|
aService := GetAnchestor(aLibrary, aService);
|
|
end;
|
|
Write('</portType>', 3);
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WriteBindings(aLibrary: TRODLLibrary; aService: TRODLService);
|
|
var o : integer;
|
|
svcname : string;
|
|
begin
|
|
// Write all the bindings for this service and its anchestors using the method names.
|
|
// It's important to notice that we NEVER use the anchestor name when composing the SOAPAction, but
|
|
// always use the final service name
|
|
if aService.isPrivate then Exit;
|
|
svcname := aService.Name;
|
|
|
|
Write(Format('<binding name="%sBinding" type="tns:%s">', [svcname, svcname]), 3);
|
|
WriteAnnotation(aService.Documentation, 6); {Giovanni}
|
|
if fUseDocument then
|
|
Write('<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />', 6)
|
|
else
|
|
Write('<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />', 6);
|
|
|
|
while Assigned(aService) and not aService.isPrivate do begin
|
|
|
|
for o := 0 to (aService.Default.Count-1) do begin
|
|
with aService.Default.Items[o] do begin
|
|
Write(Format('<operation name="%s">', [Name]), 9);
|
|
if fUseDocument then
|
|
Write(Format('<soap:operation soapAction="urn:%s-%s#%s" style="document" />', [aLibrary.Name, svcname, Name]),12)
|
|
else
|
|
Write(Format('<soap:operation soapAction="urn:%s-%s#%s" style="rpc" />', [aLibrary.Name, svcname, Name]),12);
|
|
if fUseLiteral then begin
|
|
Write('<input>', 12);
|
|
Write('<soap:body use="literal" />', 15);
|
|
if fShowClientId and fUseDocument then
|
|
write('<soap:header message="tns:ROClientIDHeaderMessage" use="literal" part="ROClientID" />', 15);
|
|
Write('</input>', 12);
|
|
|
|
Write('<output>', 12);
|
|
Write('<soap:body use="literal" />', 15);
|
|
if fShowClientId and fUseDocument then
|
|
write('<soap:header message="tns:ROClientIDHeaderMessage" use="literal" part="ROClientID" />', 15);
|
|
Write('</output>', 12);
|
|
end
|
|
else begin
|
|
Write('<input>', 12);
|
|
Write(Format('<soap:body use="encoded" '+
|
|
'encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" '+
|
|
'namespace="urn:%s-%s" />',
|
|
[aLibrary.Name, svcname]), 15);
|
|
Write('</input>', 12);
|
|
|
|
Write('<output>', 12);
|
|
Write(Format('<soap:body use="encoded" '+
|
|
'encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" '+
|
|
'namespace="urn:%s-%s" />',
|
|
[aLibrary.Name, svcname]), 15);
|
|
Write('</output>', 12);
|
|
end;
|
|
|
|
Write('</operation>', 9);
|
|
end;
|
|
end;
|
|
|
|
aService := GetAnchestor(aLibrary, aService);
|
|
end;
|
|
|
|
Write('</binding>', 3);
|
|
end;
|
|
|
|
|
|
procedure TRODLToWSDL.WriteAnnotation(aDocString: string; aIndentation: Integer
|
|
= 0; aNs: string = 'xs:');
|
|
begin
|
|
Write(Format('<%sannotation>',[aNs]), aIndentation);
|
|
WriteDocumentation(aDocString,aIndentation+3);
|
|
Write(Format('</%sannotation>',[aNs]), aIndentation);
|
|
end;
|
|
|
|
|
|
procedure TRODLToWSDL.WriteDocumentation(aDocString: string; aIndentation:
|
|
Integer = 0; aNs: string = 'xs:');
|
|
begin
|
|
Write(Format('<%sdocumentation>',[aNs]), aIndentation);
|
|
Write(Format('%s', [aDocString]),aIndentation);
|
|
Write(Format('</%sdocumentation>',[aNs]), aIndentation);
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WriteService(aLibrary: TRODLLibrary; aService: TRODLService);
|
|
begin
|
|
// We only write the service itself, ignoring the anchestors
|
|
if aService.isPrivate then Exit;
|
|
Write(Format('<service name="%sService">', [aService.Name]), 3);
|
|
WriteAnnotation(aService.Default.Documentation, 6);
|
|
|
|
while Assigned(aService) and not aService.isPrivate do begin
|
|
Write(Format('<port name="%sPort" binding="tns:%sBinding">',
|
|
[aService.Name, aService.Name]), 6);
|
|
Write(Format('<soap:address location="%s" />', [fLocation]), 9);
|
|
Write('</port>', 6);
|
|
|
|
aService := NIL;//GetAnchestor(aLibrary, aService);
|
|
end;
|
|
|
|
Write('</service>',3);
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WriteStruct(const aLibrary: TRODLLibrary; aStruct: TRODLStruct);
|
|
var
|
|
i : integer;
|
|
begin
|
|
if fExternalTypesAsReferences and (aStruct.Attributes.Values['ImportedFromUrl'] <> '') then exit;
|
|
Write(Format('<xs:complexType name="%s">', [aStruct.Name]), 9);
|
|
WriteAnnotation(aStruct.Documentation, 9); {Giovanni}
|
|
Write('<xs:sequence>', 12);
|
|
while Assigned(aStruct) do begin
|
|
for i := 0 to aStruct.Count-1 do
|
|
with aStruct.Items[i] do begin
|
|
Write(Format('<xs:element name="%s" type="%s">', [Name, ExtSOAPDataType(aLibrary, DataType)]), 15);
|
|
WriteAnnotation(Documentation, 15); {Giovanni}
|
|
Write('</xs:element>',15);
|
|
end;
|
|
|
|
if aStruct.Ancestor <> '' then begin
|
|
aStruct := aLibrary.FindStruct(aStruct.Ancestor)
|
|
end
|
|
else begin
|
|
aStruct := nil;
|
|
end;
|
|
end;
|
|
Write('</xs:sequence>', 12);
|
|
Write('</xs:complexType>', 9);
|
|
end;
|
|
|
|
procedure TRODLToWSDL.WriteLiteralParameters(aLibrary: TRODLLibrary;
|
|
aService: TRODLService);
|
|
var o, p, i : integer;
|
|
dups : TStringList;
|
|
s, svcname, mtdname : string;
|
|
op : TRODLOperation;
|
|
begin
|
|
// Writes all the methods of this service and its anchestors.
|
|
// If more than one service descend from the same base one, the WSDL has to be generated
|
|
// using a format like this: http://localhost:8099/SOAP?Service=ServiceOne
|
|
|
|
svcname := aService.Name;
|
|
dups := TStringList.Create;
|
|
dups.Duplicates := dupIgnore;
|
|
dups.Sorted := TRUE;
|
|
try
|
|
while Assigned(aService) and not aService.isPrivate do begin
|
|
|
|
for o := 0 to (aService.Default.Count-1) do begin
|
|
op := aService.Default.Items[o];
|
|
|
|
// If a method with this name is present, it skips it
|
|
mtdname := UpperCase(op.Name);
|
|
if (dups.IndexOf(mtdname)>=0) then Continue else dups.Add(mtdname);
|
|
|
|
s := op.Attributes.Values['SOAPInputName'];
|
|
if s = '' then s := Format('%s___%s', [svcname, op.Name]);
|
|
|
|
p := 0;
|
|
for i := 0 to op.Count -1 do begin
|
|
if op[i].Flag in [fIn, fInOut] then
|
|
inc(p);
|
|
end;
|
|
write(Format('<xs:element name="%s">', [s]), 3);
|
|
if p = 0 then begin
|
|
write('<xs:complexType />', 6);
|
|
end
|
|
else begin
|
|
write('<xs:complexType>', 6);
|
|
write('<xs:sequence>', 9);
|
|
for i := 0 to op.Count -1 do begin
|
|
if op[i].Flag in [fIn, fInOut] then
|
|
write(Format('<xs:element name="%s" minOccurs="1" maxOccurs="1" type="%s" />', [op[i].Name, ExtSOAPDataType(aLibrary, op[i].DataType)]), 12);
|
|
end;
|
|
write('</xs:sequence>', 9);
|
|
write('</xs:complexType>', 6);
|
|
end;
|
|
write('</xs:element>', 3);
|
|
|
|
s := op.Attributes.Values['SOAPOutputName'];
|
|
if s = '' then s := Format('%s___%sResponse', [svcname, op.Name]);
|
|
p := 0;
|
|
for i := 0 to op.Count -1 do begin
|
|
if op[i].Flag in [fOut, fInOut, fResult] then
|
|
inc(p);
|
|
end;
|
|
if op.Result <> nil then begin
|
|
inc(p);
|
|
end;
|
|
write(Format('<xs:element name="%s">', [s]), 3);
|
|
if p = 0 then begin
|
|
write('<xs:complexType />', 6);
|
|
end
|
|
else begin
|
|
write('<xs:complexType>', 6);
|
|
write('<xs:sequence>', 9);
|
|
for i := 0 to op.Count -1 do begin
|
|
if op[i].Flag in [fOut, fInOut, fResult] then
|
|
write(Format('<xs:element name="%s" minOccurs="1" maxOccurs="1" type="%s" />', [op[i].Name, ExtSOAPDataType(aLibrary, op[i].DataType)]), 12);
|
|
end;
|
|
if op.Result <> nil then
|
|
write(Format('<xs:element name="%s" minOccurs="1" maxOccurs="1" type="%s" />', [op.Result.Name, ExtSOAPDataType(aLibrary, op.Result.DataType)]), 12);
|
|
write('</xs:sequence>', 9);
|
|
write('</xs:complexType>', 6);
|
|
end;
|
|
write('</xs:element>', 3);
|
|
end;
|
|
aService := GetAnchestor(aLibrary, aService);
|
|
end;
|
|
finally
|
|
dups.Free;
|
|
end;
|
|
end;
|
|
|
|
constructor TRODLToWSDL.Create(const aLibraryFile, aTargetEntity: string);
|
|
begin
|
|
fTargetNamespace := 'http://tempuri.org/';
|
|
fExternalRefs := TStringList.Create;
|
|
fExternalUrls := TStringList.Create;
|
|
inherited;
|
|
end;
|
|
|
|
constructor TRODLToWSDL.Create(const aLibrary: TRODLLibrary;
|
|
const aTargetEntity: string);
|
|
begin
|
|
fTargetNamespace := 'http://tempuri.org/';
|
|
fExternalRefs := TStringList.Create;
|
|
fExternalUrls := TStringList.Create;
|
|
inherited;
|
|
end;
|
|
|
|
destructor TRODLToWSDL.Destroy;
|
|
begin
|
|
fExternalRefs.Free;
|
|
fExternalUrls.Free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TRODLToWSDL.AddExternal(aNode: TRODLEntity);
|
|
begin
|
|
if aNode.Attributes.Values['ImportedFromUrl'] = '' then exit;
|
|
if fExternalRefs.IndexOf(aNode.Attributes.Values['ImportedFromNamespace']) <> -1 then exit;
|
|
fExternalRefs.Add(aNode.Attributes.Values['ImportedFromNamespace']);
|
|
fExternalUrls.ADd(aNode.Attributes.Values['ImportedFromUrl']);
|
|
end;
|
|
|
|
function TRODLToWSDL.ExtSOAPDataType(aLibrary: TRODLLibrary; const aDataTypeName: string): string;
|
|
var
|
|
el: TRODLEntity;
|
|
begin
|
|
if fExternalTypesAsReferences then begin
|
|
el := aLibrary.FindStruct(aDataTypeName);
|
|
if el = nil then
|
|
el := aLibrary.FindEnum(aDataTypeName);
|
|
if el = nil then
|
|
el := aLibrary.FindArray(aDataTypeName);
|
|
if el <> nil then begin
|
|
if el.Attributes.values['ImportedFromNamespace'] <> '' then begin
|
|
result := 'ns'+IntToStr(fExternalRefs.IndexOf(el.Attributes.values['ImportedFromNamespace']))+':'+aDataTypeName;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
result := SOAPDataType(aDataTypeName, True);
|
|
end;
|
|
|
|
end.
|