1 /**
2 * Copyright © DiamondMVC 2019
3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module diamond.web.soap.service.parser.wsdlparser;
7 
8 import std..string : format;
9 import std.file : write, exists, mkdir;
10 
11 import diamond.dom;
12 import diamond.xml;
13 
14 /**
15 * Parses a wsdl document into a d module.
16 * Params:
17 *   name =       The name of the service.
18 *   wsdl =       The path to the wsdl file.
19 *   document =   The wsdl document.
20 *   moduleName = The name of the resulting d module.
21 */
22 package(diamond.web.soap.service) void parseWsdl(string name, string wsdl, XmlDocument document, string moduleName)
23 {
24   import diamond.web.soap.service.parser.typeparser;
25   import diamond.web.soap.service.parser.messageparser;
26   import diamond.web.soap.service.parser.porttypeparser;
27   import diamond.web.soap.service.parser.bindingparser;
28   import diamond.web.soap.service.parser.serviceparser;
29 
30   auto types = document.root.getByTagName("types");
31 
32   if (!types || types.length != 1)
33   {
34     types = document.root.getByTagName("wsdl:types");
35   }
36 
37   if (!types || types.length != 1)
38   {
39     types = document.root.getByTagName("xs:types");
40   }
41 
42   if (!types || types.length != 1)
43   {
44     types = document.root.getByTagName("xsd:types");
45   }
46 
47   if (!types || types.length != 1)
48   {
49     return;
50   }
51 
52   auto schemas = types[0].getByTagName("xs:schema");
53 
54   if (!schemas || !schemas.length)
55   {
56     schemas = types[0].getByTagName("xsd:schema");
57   }
58 
59   if (!schemas || !schemas.length)
60   {
61     schemas = types[0].getByTagName("wsdl:schema");
62   }
63 
64   if (!schemas || !schemas.length)
65   {
66     schemas = types[0].getByTagName("schema");
67   }
68 
69   if (!schemas || !schemas.length)
70   {
71     return;
72   }
73 
74   string wsdlResult = q{/**
75 * This file was generated by Diamond MVC - https://diamondmvc.org/
76 * Service: %s
77 * Module: %s
78 * Wsdl: %s
79 */
80 module %s;
81 
82 import __stdtraits = std.traits;
83 
84 import diamond.web.soap.datatypes;
85 import diamond.web.soap.client;
86 
87 }.format(name, moduleName, wsdl, moduleName);
88 
89   string[] typeNames;
90 
91   foreach (schema; schemas)
92   {
93     auto result = parseSchema(schema);
94 
95     if (result && result.length)
96     {
97       import std.algorithm : filter, map;
98       import std.array : array;
99 
100       typeNames ~= result.filter!(r => r.name && r.name.length).map!(r => r.name).array;
101 
102       wsdlResult ~= parseDTypes(result);
103     }
104   }
105 
106   import diamond.core.collections;
107   import diamond.web.soap.service.message;
108 
109   SoapMessage[string] inputs;
110   SoapMessage[string] outputs;
111   parseMessages(moduleName, new HashSet!string(typeNames), document.root, inputs, outputs);
112 
113   import diamond.web.soap.service.messageoperation;
114 
115   SoapMessageOperation[][string] messageOperations;
116   wsdlResult ~= parsePortTypes(document.root, inputs, outputs, messageOperations);
117 
118   wsdlResult ~= parseBinding(document.root, messageOperations);
119 
120   wsdlResult ~= parseServices(document.root);
121 
122   if (!exists("__services"))
123   {
124     mkdir("__services");
125   }
126 
127   write("__services/" ~ name ~ ".d", wsdlResult);
128   write("__services/" ~ name ~ ".wsdl.xml", document.toString());
129 }