コード例 #1
0
ファイル: SerializerCache.cs プロジェクト: jaxx/XRoadLib
        private IServiceMap AddServiceMap(XName qualifiedName)
        {
            var operationDefinition = GetOperationDefinition(contractAssembly, qualifiedName);

            if (operationDefinition == null || qualifiedName.NamespaceName != operationDefinition.Name.NamespaceName)
            {
                throw XRoadException.UnknownOperation(qualifiedName);
            }

            var requestValueDefinition = schemaDefinitionProvider.GetRequestValueDefinition(operationDefinition);
            var inputTypeMap           = GetContentDefinitionTypeMap(requestValueDefinition, null);

            var outputTuple             = GetReturnValueTypeMap(operationDefinition);
            var responseValueDefinition = outputTuple.Item1;
            var outputTypeMap           = outputTuple.Item2;

            var serviceMap = (IServiceMap)Activator.CreateInstance(
                operationDefinition.ServiceMapType,
                this,
                operationDefinition,
                requestValueDefinition,
                responseValueDefinition,
                inputTypeMap,
                outputTypeMap
                );

            return(serviceMaps.GetOrAdd(qualifiedName, serviceMap));
        }
コード例 #2
0
        private IEnumerable <XmlSchema> BuildSchemas(string targetNamespace, MessageCollection messages)
        {
            var schemaTypes     = new List <Tuple <string, XmlSchemaType> >();
            var schemaElements  = new List <XmlSchemaElement>();
            var referencedTypes = new Dictionary <XmlQualifiedName, XmlSchemaType>();

            var faultDefinition = schemaDefinitionProvider.GetFaultDefinition();
            var addFaultType    = false;

            foreach (var operationDefinition in GetOperationDefinitions(targetNamespace))
            {
                var requestValueDefinition = schemaDefinitionProvider.GetRequestValueDefinition(operationDefinition);

                Func <XmlSchemaElement> createRequestElement = () => requestValueDefinition.ParameterInfo != null
                    ? CreateContentElement(requestValueDefinition, targetNamespace, referencedTypes)
                    : new XmlSchemaElement
                {
                    Name = requestValueDefinition.RequestElementName, SchemaType = new XmlSchemaComplexType {
                        Particle = new XmlSchemaSequence()
                    }
                };

                var requestElement = createRequestElement();
                AddCustomAttributes(requestValueDefinition, requestElement, ns => addRequiredImport(targetNamespace, ns, operationDefinition.ExtensionSchemaExporter));

                if (protocol.Style.UseElementInMessagePart)
                {
                    schemaElements.Add(new XmlSchemaElement
                    {
                        Name       = operationDefinition.Name.LocalName,
                        SchemaType = new XmlSchemaComplexType {
                            Particle = new XmlSchemaSequence {
                                Items = { requestElement }
                            }
                        }
                    });
                }

                var responseValueDefinition = schemaDefinitionProvider.GetResponseValueDefinition(operationDefinition);
                if (!responseValueDefinition.ContainsNonTechnicalFault)
                {
                    addFaultType = true;
                }

                XmlSchemaElement responseElement;
                XmlSchemaElement resultElement = null;

                if (responseValueDefinition.XRoadFaultPresentation != XRoadFaultPresentation.Implicit && responseValueDefinition.ContainsNonTechnicalFault)
                {
                    var outputParticle = new XmlSchemaSequence();
                    responseElement = new XmlSchemaElement {
                        Name = responseValueDefinition.ResponseElementName, SchemaType = new XmlSchemaComplexType {
                            Particle = outputParticle
                        }
                    };

                    var faultSequence = CreateFaultSequence();

                    if (operationDefinition.MethodInfo.ReturnType == typeof(void))
                    {
                        faultSequence.MinOccurs = 0;
                        outputParticle.Items.Add(faultSequence);
                    }
                    else if (responseValueDefinition.XRoadFaultPresentation == XRoadFaultPresentation.Choice)
                    {
                        resultElement = CreateContentElement(responseValueDefinition, targetNamespace, referencedTypes);
                        outputParticle.Items.Add(new XmlSchemaChoice {
                            Items = { resultElement, faultSequence }
                        });
                    }
                    else
                    {
                        resultElement           = CreateContentElement(responseValueDefinition, targetNamespace, referencedTypes);
                        resultElement.MinOccurs = 0;
                        outputParticle.Items.Add(resultElement);

                        faultSequence.MinOccurs = 0;
                        outputParticle.Items.Add(faultSequence);
                    }
                }
                else
                {
                    responseElement = resultElement = CreateContentElement(responseValueDefinition, targetNamespace, referencedTypes);
                }

                AddCustomAttributes(responseValueDefinition, responseElement, ns => addRequiredImport(targetNamespace, ns, operationDefinition.ExtensionSchemaExporter));

                if (protocol.Style.UseElementInMessagePart)
                {
                    var responseRequestElement = requestElement;
                    if (requestValueDefinition.RequestElementName != responseValueDefinition.RequestElementName)
                    {
                        responseRequestElement      = createRequestElement();
                        responseRequestElement.Name = responseValueDefinition.RequestElementName;
                    }
                    schemaElements.Add(new XmlSchemaElement
                    {
                        Name       = $"{operationDefinition.Name.LocalName}Response",
                        SchemaType = CreateOperationResponseSchemaType(responseValueDefinition, responseRequestElement, responseElement, faultDefinition)
                    });
                }

                if (operationDefinition.IsAbstract)
                {
                    continue;
                }

                var inputMessage = new Message {
                    Name = operationDefinition.InputMessageName
                };

                if (protocol.Style.UseElementInMessagePart)
                {
                    inputMessage.Parts.Add(new MessagePart {
                        Name = "body", Element = new XmlQualifiedName(operationDefinition.Name.LocalName, operationDefinition.Name.NamespaceName)
                    });
                }
                else
                {
                    var requestTypeName = requestElement?.SchemaTypeName;
                    inputMessage.Parts.Add(new MessagePart {
                        Name = requestValueDefinition.RequestElementName, Type = requestTypeName
                    });
                }

                if (operationDefinition.InputBinaryMode == BinaryMode.Attachment)
                {
                    inputMessage.Parts.Add(new MessagePart {
                        Name = "file", Type = new XmlQualifiedName("base64Binary", NamespaceConstants.XSD)
                    });
                }

                messages.Add(inputMessage);

                var outputMessage = new Message {
                    Name = operationDefinition.OutputMessageName
                };

                if (protocol.Style.UseElementInMessagePart)
                {
                    outputMessage.Parts.Add(new MessagePart {
                        Name = "body", Element = new XmlQualifiedName($"{operationDefinition.Name.LocalName}Response", operationDefinition.Name.NamespaceName)
                    });
                }
                else
                {
                    var requestTypeName  = requestElement?.SchemaTypeName;
                    var responseTypeName = GetOutputMessageTypeName(resultElement, operationDefinition.MethodInfo.ReturnType, schemaTypes);
                    outputMessage.Parts.Add(new MessagePart {
                        Name = responseValueDefinition.RequestElementName, Type = requestTypeName
                    });
                    outputMessage.Parts.Add(new MessagePart {
                        Name = responseValueDefinition.ResponseElementName, Type = responseTypeName
                    });
                }

                if (operationDefinition.OutputBinaryMode == BinaryMode.Attachment)
                {
                    outputMessage.Parts.Add(new MessagePart {
                        Name = "file", Type = new XmlQualifiedName("base64Binary", NamespaceConstants.XSD)
                    });
                }

                messages.Add(outputMessage);

                AddPortTypeOperation(operationDefinition, inputMessage, outputMessage, targetNamespace);

                AddBindingOperation(operationDefinition);
            }

            int initialCount;

            do
            {
                initialCount = referencedTypes.Count;

                foreach (var kvp in referencedTypes.ToList().Where(x => x.Value == null))
                {
                    TypeDefinition typeDefinition;
                    if (!schemaTypeDefinitions.TryGetValue(XName.Get(kvp.Key.Name, kvp.Key.Namespace), out typeDefinition))
                    {
                        continue;
                    }

                    if (typeDefinition.IsSimpleType)
                    {
                        continue;
                    }

                    XmlSchemaType schemaType;

                    if (typeDefinition.Type.GetTypeInfo().IsEnum)
                    {
                        schemaType = new XmlSchemaSimpleType();
                        AddEnumTypeContent(typeDefinition.Type, (XmlSchemaSimpleType)schemaType);
                    }
                    else
                    {
                        schemaType = new XmlSchemaComplexType {
                            IsAbstract = typeDefinition.Type.GetTypeInfo().IsAbstract
                        };

                        if (AddComplexTypeContent((XmlSchemaComplexType)schemaType, typeDefinition.Name.NamespaceName, typeDefinition, referencedTypes) != null)
                        {
                            throw new NotImplementedException();
                        }
                    }

                    schemaType.Name       = typeDefinition.Name.LocalName;
                    schemaType.Annotation = CreateSchemaAnnotation(typeDefinition.Name.NamespaceName, typeDefinition);

                    AddSchemaType(schemaTypes, typeDefinition.Name.NamespaceName, schemaType);

                    referencedTypes[kvp.Key] = schemaType;

                    List <Type> typeList;
                    if (!derivedTypes.TryGetValue(typeDefinition.Type, out typeList))
                    {
                        continue;
                    }

                    foreach (var qualifiedName in typeList.Select(x => runtimeTypeDefinitions[x]).Select(x => new XmlQualifiedName(x.Name.LocalName, x.Name.NamespaceName)).Where(x => !referencedTypes.ContainsKey(x)))
                    {
                        referencedTypes.Add(qualifiedName, null);
                    }
                }
            } while (initialCount != referencedTypes.Count);

            if (addFaultType && faultDefinition.State == DefinitionState.Default)
            {
                AddSchemaType(schemaTypes, faultDefinition.Name.NamespaceName, new XmlSchemaComplexType
                {
                    Name       = faultDefinition.Name.LocalName,
                    Particle   = CreateFaultSequence(),
                    Annotation = CreateSchemaAnnotation(faultDefinition.Name.NamespaceName, faultDefinition)
                });
            }

            return(schemaTypes
                   .Select(x => x.Item1)
                   .Where(x => x != NamespaceConstants.XSD && x != targetNamespace)
                   .Distinct()
                   .Where(ns => schemaLocations[ns] == null)
                   .Select(x => BuildSchemaForNamespace(x, schemaTypes, null))
                   .Concat(new [] { BuildSchemaForNamespace(targetNamespace, schemaTypes, schemaElements) })
                   .ToList());
        }