public void WriteRequestBody(XmlWriterImpl writer, XdtoSerializerImpl serializer, IValue [] arguments) { foreach (var messagePart in Parameters.Parts) { writer.WriteStartElement(messagePart.ElementName, messagePart.NamespaceUri); foreach (var param in messagePart.Parameters) { if (param.ParameterDirection == ParameterDirectionEnum.Out) { continue; } var argumentIndex = _indexes [param.Name]; var typeAssignment = XmlTypeAssignmentEnum.Implicit; if (param.Type is XdtoValueType) { typeAssignment = XmlTypeAssignmentEnum.Explicit; } serializer.WriteXml(writer, arguments [argumentIndex], param.Name, messagePart.NamespaceUri, typeAssignment); } writer.WriteEndElement(); // messagePart.ElementName } }
public void Handle(XmlReaderImpl requestReader, XmlWriterImpl responseWriter) { var F = new XdtoFactory(); var S = XdtoSerializerImpl.Constructor(ValueFactory.Create(F)) as XdtoSerializerImpl; var inputMessage = F.ReadXml(requestReader) as XdtoDataObject; var body = inputMessage.Get("Body") as XdtoDataObject; var requestProperty = body.Properties().Get(0); var methodName = requestProperty.LocalName; if (!operations.ContainsKey(methodName)) { // TODO: SoapException throw new RuntimeException($"method not found {methodName}"); } var op = operations[methodName]; // TODO: отдать разбор в операцию var args = new List <IValue>(); var callParams = body.Get(body.Properties().Get(0)) as XdtoDataObject; foreach (var pv in callParams.Properties()) { var paramName = pv.LocalName; var p = op.Parameters.Get(paramName); var xdtoValue = callParams.GetXdto(pv); var ivalue = S.ReadXdto(xdtoValue); if (p.ParameterDirection != ParameterDirectionEnum.In) { ivalue = Variable.Create(ivalue, paramName); } args.Add(ivalue); } var handler = operationsMapper[op]; var methodIdx = handler.FindMethod(methodName); var mi = handler.GetMethodInfo(methodIdx); IValue result = null; if (mi.IsFunction) { handler.CallAsFunction(methodIdx, args.ToArray(), out result); } else { handler.CallAsProcedure(methodIdx, args.ToArray()); } op.WriteResponseBody(responseWriter, S, result, args.ToArray()); }
// Особенности реализации: возвращаемое значение и исходящие параметры // передаём ОДНИМ сообщением, хотя протокол разрешает несколько сообщений public void WriteResponseBody(XmlWriterImpl writer, XdtoSerializerImpl serializer, IValue returnValue, IValue [] arguments) { writer.WriteStartElement(ReturnValue.MessagePartName, NamespaceUri); serializer.WriteXml(writer, returnValue, "return", NamespaceUri); foreach (var param in Parameters) { if (param.ParameterDirection == ParameterDirectionEnum.In) { continue; } var argumentIndex = _indexes [param.Name]; serializer.WriteXml(writer, arguments [argumentIndex], param.Name, NamespaceUri); } writer.WriteEndElement(); // messagePartName }
public IParsedResponse ParseResponse(XmlReaderImpl reader, XdtoSerializerImpl serializer) { var retValue = ValueFactory.Create(); var outputParams = new Dictionary <int, IValue> (); var xmlNodeTypeEnum = XmlNodeTypeEnum.CreateInstance(); var xmlElementStart = xmlNodeTypeEnum.FromNativeValue(System.Xml.XmlNodeType.Element); if (!reader.Read() || !reader.LocalName.Equals("Envelope") || !reader.NodeType.Equals(xmlElementStart) // TODO: перевести XML на простые перечисления ) { return(new SoapExceptionResponse("Wrong response!")); } reader.MoveToContent(); if (!reader.Read() || !reader.LocalName.Equals("Body") || !reader.NodeType.Equals(xmlElementStart) // TODO: перевести XML на простые перечисления ) { return(new SoapExceptionResponse("Wrong response!")); } if (!reader.Read()) { return(new SoapExceptionResponse("Wrong response!")); } if (reader.LocalName.Equals("Fault") && reader.NodeType.Equals(xmlElementStart)) { reader.Read(); while (!(reader.LocalName.Equals("faultString") && reader.NodeType.Equals(xmlElementStart))) { if (!reader.Read()) { return(new SoapExceptionResponse("Wrong response!")); } } reader.Read(); var faultString = reader.Value; return(new SoapExceptionResponse(faultString)); } var xdtoResult = serializer.XdtoFactory.ReadXml(reader, ReturnValue.ResponseType ?? ReturnValue.Type) as XdtoDataObject; retValue = xdtoResult.Get("return"); if (retValue is IXdtoValue) { retValue = serializer.ReadXdto(retValue as IXdtoValue); } foreach (var param in Parameters) { if (param.ParameterDirection == ParameterDirectionEnum.In) { continue; } var argumentIndex = _indexes [param.Name]; IValue paramValue = xdtoResult.Get(param.Name); if (paramValue is IXdtoValue) { paramValue = serializer.ReadXdto(paramValue as IXdtoValue); } outputParams.Add(argumentIndex, paramValue); } return(new SuccessfulSoapResponse(retValue, outputParams)); }
public override void CallAsFunction(int methodNumber, IValue [] arguments, out IValue retValue) { var operation = _operations [methodNumber]; retValue = ValueFactory.Create(); ConnectIfNeeded(); var headers = new MapImpl(); headers.Insert(ValueFactory.Create("Content-Type"), ValueFactory.Create("application/xml")); var xmlBody = XmlWriterImpl.Create(); xmlBody.SetString(ValueFactory.Create("UTF-8")); xmlBody.WriteStartElement("soap:Envelope"); xmlBody.WriteNamespaceMapping("xsi", "http://www.w3.org/2001/XMLSchema-instance"); xmlBody.WriteNamespaceMapping("xsd", "http://www.w3.org/2001/XMLSchema"); xmlBody.WriteNamespaceMapping("soap", "http://schemas.xmlsoap.org/soap/envelope/"); xmlBody.WriteNamespaceMapping("s", Endpoint.Interface.NamespaceURI); xmlBody.WriteStartElement("soap:Body"); var serializer = XdtoSerializerImpl.Constructor(XdtoFactory) as XdtoSerializerImpl; operation.WriteRequestBody(xmlBody, serializer, arguments); xmlBody.WriteEndElement(); // soap:Body xmlBody.WriteEndElement(); // soap:Envelope var requestString = xmlBody.Close().ToString(); if (DoDebug) { Console.WriteLine(requestString); } var responseText = _transport.Handle(requestString); var xmlResult = XmlReaderImpl.Create() as XmlReaderImpl; if (DoDebug) { Console.WriteLine(responseText); } // TODO: Отдать на разбор фабрике xmlResult.SetString(responseText); var result = operation.ParseResponse(xmlResult, serializer); if (result is SoapExceptionResponse) { throw new ScriptEngine.Machine.RuntimeException((result as SoapExceptionResponse).FaultMessage); } var soapResponse = result as SuccessfulSoapResponse; retValue = soapResponse.RetValue; foreach (var outParamData in soapResponse.OutputParameters) { var argument = arguments [outParamData.Key] as IVariable; if (argument == null) { continue; } argument.Value = outParamData.Value; } }