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.porttypeparser; 7 8 import std.array : split, join; 9 import std..string : format; 10 11 import diamond.dom; 12 import diamond.xml; 13 import diamond.web.soap.service.message; 14 import diamond.web.soap.service.messageoperation; 15 import diamond.errors.exceptions.soapexception; 16 17 package(diamond.web.soap.service.parser): 18 /** 19 * Parses the port types of the wsdl file. 20 * Params: 21 * root = The root node of the wsdl file. 22 * inputs = The input messages. 23 * outputs = The output messages. 24 * messageOperations = The message operations. 25 */ 26 string parsePortTypes(XmlNode root, SoapMessage[string] inputs, SoapMessage[string] outputs, out SoapMessageOperation[][string] messageOperations) 27 { 28 static const portTypeInterfaceFormat = q{ 29 interface I%s 30 { 31 public: 32 %s 33 } 34 }; 35 36 static const portTypeOperationFormat = "\t@SoapAction(\"%s\") %s %s(%s);\r\n"; 37 38 string result = ""; 39 40 auto portTypes = root.getByTagName("wsdl:portType"); 41 42 if (!portTypes || !portTypes.length) 43 { 44 portTypes = root.getByTagName("xs:portType"); 45 } 46 47 if (!portTypes || !portTypes.length) 48 { 49 portTypes = root.getByTagName("xsd:portType"); 50 } 51 52 if (!portTypes || !portTypes.length) 53 { 54 portTypes = root.getByTagName("portType"); 55 } 56 57 if (portTypes && portTypes.length) 58 { 59 foreach (portType; portTypes) 60 { 61 auto name = portType.getAttribute("name"); 62 63 if (!name) 64 { 65 throw new SoapException("Missing name for portType."); 66 } 67 68 SoapMessageOperation[] portMessageOperations; 69 70 auto operations = portType.getByTagName("wsdl:operation"); 71 72 if (!operations || !operations.length) 73 { 74 operations = portType.getByTagName("xs:operation"); 75 } 76 77 if (!operations || !operations.length) 78 { 79 operations = portType.getByTagName("xsd:operation"); 80 } 81 82 if (!operations || !operations.length) 83 { 84 operations = portType.getByTagName("operation"); 85 } 86 87 string[] operationsResult; 88 89 if (operations && operations.length) 90 { 91 foreach (operation; operations) 92 { 93 auto operationName = operation.getAttribute("name"); 94 95 if (!operationName) 96 { 97 throw new SoapException("Missing operation name."); 98 } 99 100 auto inputTags = operation.getByTagName("wsdl:input"); 101 102 if (!inputTags || !inputTags.length) 103 { 104 inputTags = operation.getByTagName("xs:input"); 105 } 106 107 if (!inputTags || !inputTags.length) 108 { 109 inputTags = operation.getByTagName("xsd:input"); 110 } 111 112 if (!inputTags || !inputTags.length) 113 { 114 inputTags = operation.getByTagName("input"); 115 } 116 117 if (!inputTags || !inputTags.length) 118 { 119 throw new SoapException("Missing input from operation."); 120 } 121 122 auto outputTags = operation.getByTagName("wsdl:output"); 123 124 if (!outputTags || !outputTags.length) 125 { 126 outputTags = operation.getByTagName("xs:output"); 127 } 128 129 if (!outputTags || !outputTags.length) 130 { 131 outputTags = operation.getByTagName("xsd:output"); 132 } 133 134 if (!outputTags || !outputTags.length) 135 { 136 outputTags = operation.getByTagName("output"); 137 } 138 139 if (!outputTags || !outputTags.length) 140 { 141 throw new SoapException("Missing output for operation."); 142 } 143 144 auto input = inputTags[0]; 145 auto output = outputTags[0]; 146 147 auto inputName = input.getAttribute("message").value; 148 149 if (inputName.split(":").length == 2) 150 { 151 inputName = inputName.split(":")[1]; 152 } 153 154 auto inputParameters = inputs.get(inputName, null); 155 156 auto outputName = output.getAttribute("message").value; 157 158 if (outputName.split(":").length == 2) 159 { 160 outputName = outputName.split(":")[1]; 161 } 162 163 auto outputParameters = outputs.get(outputName, null); 164 165 if (!outputParameters || !outputParameters.output) 166 { 167 throw new SoapException("Missing output parameters."); 168 } 169 170 auto action = input.getAttribute("wsaw:action"); 171 172 if (!action) 173 { 174 action = input.getAttribute("wsdl:action"); 175 } 176 177 if (!action) 178 { 179 action = input.getAttribute("xs:action"); 180 } 181 182 if (!action) 183 { 184 action = input.getAttribute("xsd:action"); 185 } 186 187 if (!action) 188 { 189 action = input.getAttribute("action"); 190 } 191 192 if (!action) 193 { 194 action = output.getAttribute("wsaw:action"); 195 } 196 197 if (!action) 198 { 199 action = output.getAttribute("wsdl:action"); 200 } 201 202 if (!action) 203 { 204 action = output.getAttribute("xs:action"); 205 } 206 207 if (!action) 208 { 209 action = output.getAttribute("xsd:action"); 210 } 211 212 if (!action) 213 { 214 action = output.getAttribute("action"); 215 } 216 217 auto returnType = outputParameters.output.type; 218 219 string[] parameters; 220 221 if (inputParameters && inputParameters.input && inputParameters.input.length) 222 { 223 foreach (inputParameter; inputParameters.input) 224 { 225 parameters ~= "%s %s".format(inputParameter.type, inputParameter.name); 226 } 227 } 228 229 auto portMessageOperation = new SoapMessageOperation(action ? action.value : "", operationName.value, returnType, parameters ? parameters.join(",") : ""); 230 231 portMessageOperations ~= portMessageOperation; 232 233 operationsResult ~= portTypeOperationFormat.format(portMessageOperation.action, portMessageOperation.returnType, portMessageOperation.name, portMessageOperation.parameters); 234 } 235 } 236 237 if (portMessageOperations) 238 { 239 messageOperations[name.value] = portMessageOperations; 240 } 241 242 result ~= portTypeInterfaceFormat.format(name.value, operationsResult ? operationsResult.join("\r\n") : ""); 243 } 244 } 245 246 return result; 247 }