From 4edd9df7fad17020e3c68ba62c7b6badda9276a3 Mon Sep 17 00:00:00 2001 From: inoussa Date: Thu, 1 May 2014 16:58:45 +0000 Subject: [PATCH] Better XSD/WSDL generation : "import" nodes are correctly generated. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2983 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- wst/trunk/ws_helper/pascal_parser_intf.pas | 3 ++ wst/trunk/ws_helper/wsdl_generator.pas | 38 +++++++++++++++----- wst/trunk/ws_helper/wsdl_parser.pas | 2 ++ wst/trunk/ws_helper/xsd_generator.pas | 40 ++++++++++++++++++++++ wst/trunk/ws_helper/xsd_parser.pas | 2 ++ 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/wst/trunk/ws_helper/pascal_parser_intf.pas b/wst/trunk/ws_helper/pascal_parser_intf.pas index ec43543b4..023b05705 100644 --- a/wst/trunk/ws_helper/pascal_parser_intf.pas +++ b/wst/trunk/ws_helper/pascal_parser_intf.pas @@ -30,6 +30,9 @@ const sARRAY_STYLE_EMBEDDED = 'ARRAY_STYLE_EMBEDDED'; sARRAY_IS_COLLECTION = 'ARRAY_COLLECTION'; sWST_PROP_STORE_PREFIX = 'wstHas_'; + sFILE_NAME = 'FileName'; + sNS_COUNT = 'NS_Count'; + sNS_ITEM = 'NS_'; sXSD_NS = 'http://www.w3.org/2001/XMLSchema'; diff --git a/wst/trunk/ws_helper/wsdl_generator.pas b/wst/trunk/ws_helper/wsdl_generator.pas index 059af8420..1598ff05a 100644 --- a/wst/trunk/ws_helper/wsdl_generator.pas +++ b/wst/trunk/ws_helper/wsdl_generator.pas @@ -43,7 +43,7 @@ type FTypesNode : TDOMElement; FDefinitionsNode : TDOMElement; private - procedure GenerateTypes(ASymTable : TwstPasTreeContainer); + procedure GenerateTypes(ASymTable : TwstPasTreeContainer; AModule : TPasModule); procedure GenerateServiceMessages( ASymTable : TwstPasTreeContainer; AModule : TPasModule; @@ -143,21 +143,43 @@ end; { TWsdlGenerator } -procedure TWsdlGenerator.GenerateTypes(ASymTable : TwstPasTreeContainer); +procedure TWsdlGenerator.GenerateTypes( + ASymTable : TwstPasTreeContainer; + AModule : TPasModule +); var - i : PtrInt; + i, c : PtrInt; mdl : TPasModule; mdlLs : TList2; g : IGenerator; + nsList : TStringList; + s : string; begin mdlLs := ASymTable.Package.Modules; if ( mdlLs.Count > 0 ) then begin - g := TWsdlTypechemaGenerator.Create(Document) as IGenerator; - for i := 0 to Pred(mdlLs.Count) do begin - mdl := TPasModule(mdlLs[i]); - if not mdl.InheritsFrom(TPasNativeModule) then begin + nsList := TStringList.Create(); + try + c := StrToIntDef(ASymTable.Properties.GetValue(AModule,sNS_COUNT),0); + if (c > 0) then begin + for i := 1 to c do begin + s := ASymTable.Properties.GetValue(AModule,sNS_ITEM+IntToStr(i)); + nsList.Add(s); + end; + end; + g := TWsdlTypechemaGenerator.Create(Document) as IGenerator; + for i := 0 to Pred(mdlLs.Count) do begin + if (mdl <> AModule) then begin + mdl := TPasModule(mdlLs[i]); + if mdl.InheritsFrom(TPasNativeModule) then + Continue; + s := ASymTable.GetExternalName(mdl); + if (nsList.IndexOf(s) = -1) then + Continue; + end; g.Execute(ASymTable,mdl.Name); end; + finally + nsList.Free(); end; end; end; @@ -463,7 +485,7 @@ begin raise EWsdlGeneratorException.Create('Invalid symbol table.'); Prepare(ASymTable,locMainModule); - GenerateTypes(ASymTable); + GenerateTypes(ASymTable,locMainModule); decList := locMainModule.InterfaceSection.Declarations; c := decList.Count; diff --git a/wst/trunk/ws_helper/wsdl_parser.pas b/wst/trunk/ws_helper/wsdl_parser.pas index e2b0e010a..482206c4a 100644 --- a/wst/trunk/ws_helper/wsdl_parser.pas +++ b/wst/trunk/ws_helper/wsdl_parser.pas @@ -438,8 +438,10 @@ procedure TWsdlParser.Execute(const AMode: TParserMode; const AModuleName: strin locModule : TPasModule; locIntfUsesList : TList2; begin + FSymbols.Properties.SetValue(FModule,sNS_COUNT,IntToStr(FXsdParsers.Count)); locIntfUsesList := FModule.InterfaceSection.UsesList; for k := 0 to Pred(FXsdParsers.Count) do begin + FSymbols.Properties.SetValue(FModule,(sNS_ITEM+IntToStr(k+1)),FXsdParsers[k]); locPrs := (FXsdParsers.Objects[k] as TIntfObjectRef).Intf as IParserContext; locModule := locPrs.GetTargetModule(); if (locModule <> nil) and (locModule <> FModule) and diff --git a/wst/trunk/ws_helper/xsd_generator.pas b/wst/trunk/ws_helper/xsd_generator.pas index 5263f1fce..5324b71d0 100644 --- a/wst/trunk/ws_helper/xsd_generator.pas +++ b/wst/trunk/ws_helper/xsd_generator.pas @@ -88,6 +88,11 @@ type FDocument : TDOMDocument; FOptions: TGeneratorOptions; FShortNames : TStrings; + protected + procedure GenerateImports( + ASymTable : TwstPasTreeContainer; + AModule : TPasModule + ); protected function GetSchemaNode(ADocument : TDOMDocument) : TDOMNode;virtual;abstract; procedure SetPreferedShortNames(const ALongName, AShortName : string); @@ -1335,6 +1340,7 @@ begin if ( mdl = nil ) then raise EXsdGeneratorException.CreateFmt('Unable to find module : "%s".',[AModuleName]); Prepare(ASymTable,mdl); + GenerateImports(ASymTable,mdl); gr := GetXsdTypeHandlerRegistry(); typeList := mdl.InterfaceSection.Declarations; k := typeList.Count; @@ -1397,6 +1403,40 @@ begin SetPreferedShortNames(s_wsdl,'wsdl'); end; +procedure TCustomXsdGenerator.GenerateImports( + ASymTable : TwstPasTreeContainer; + AModule : TPasModule +); +var + locUsesList : TList2; + locModule : TPasElement; + i : Integer; + locNS, locFileName, s : string; + locSchemaNode, resNode : TDOMElement; + locCurrentNS : string; +begin + locUsesList := AModule.InterfaceSection.UsesList; + if (locUsesList.Count > 0) then begin + locCurrentNS := ASymTable.GetExternalName(AModule); + for i := 0 to Pred(locUsesList.Count) do begin + locModule := TPasElement(locUsesList[i]); + locNS := ASymTable.GetExternalName(locModule); + if SameText(locCurrentNS,locNS) then + Continue; + if locModule.InheritsFrom(TPasNativeModule) then + Continue; + locFileName := ASymTable.Properties.GetValue(locModule,sFILE_NAME); + if IsStrEmpty(locFileName) then + Continue; + locSchemaNode := GetSchemaNode(FDocument) as TDOMElement; + s := Format('%s:%s',[s_xs_short,s_import]); + resNode := CreateElement(s,locSchemaNode,FDocument); + resNode.SetAttribute(s_namespace,locNS); + resNode.SetAttribute(s_schemaLocation,locFileName); + end; + end; +end; + procedure TCustomXsdGenerator.SetPreferedShortNames(const ALongName, AShortName: string); begin FShortNames.Values[ALongName] := AShortName; diff --git a/wst/trunk/ws_helper/xsd_parser.pas b/wst/trunk/ws_helper/xsd_parser.pas index cd08ba01b..9846e1cd2 100644 --- a/wst/trunk/ws_helper/xsd_parser.pas +++ b/wst/trunk/ws_helper/xsd_parser.pas @@ -994,6 +994,8 @@ begin locModule.Name := locName; locModule.AddRef(); locUsesList.Add(locModule); + if (FSymbols.Properties.GetValue(locModule,sFILE_NAME) = '') then + FSymbols.Properties.SetValue(locModule,sFILE_NAME,locFileName); end; end; end else begin