private WsdlFileInfo GetMainWsdl()
        {
            var importedWsdl = new List <string>();
            var wsdlFiles    = this.MetadataFiles.OfType <WsdlFileInfo>();

            // record imported wsld files to be able to identify the core wsdl file.
            foreach (var wsdl in wsdlFiles.Select(f => f.Wsdl))
            {
                foreach (WsdlNS.Import import in wsdl.Imports)
                {
                    var filePath = Path.Combine(this.DirectoryPath, import.Location);
                    importedWsdl.Add(filePath);
                }
            }

            var mainWsdlFile = wsdlFiles.Where(w => !importedWsdl.Any(i => MetadataFileNameManager.UriEqual(i, w.FilePath))).FirstOrDefault();

            if (mainWsdlFile == null)
            {
                // this may be the case of docs with circular dependencies, this is ok as they are not imported multiple times, select the first one (if any).
                mainWsdlFile = wsdlFiles.FirstOrDefault();
            }

            return(mainWsdlFile);
        }
        /// <summary>
        /// </summary>
        /// <param name="uri">The service Uri to load service metadata from.</param>
        /// <param name="httpCredentialsProvider"></param>
        /// <param name="clientCertificatesProvider"></param>
        /// <param name="serverCertificateValidationProvider"></param>
        public MetadataDocumentLoader(string uri, IHttpCredentialsProvider httpCredentialsProvider, IClientCertificateProvider clientCertificatesProvider, IServerCertificateValidationProvider serverCertificateValidationProvider)
        {
            _httpCredentialsProvider             = httpCredentialsProvider;
            _clientCertificatesProvider          = clientCertificatesProvider;
            _serverCertificateValidationProvider = serverCertificateValidationProvider;

            if (string.IsNullOrEmpty(uri))
            {
                throw new ArgumentNullException(nameof(uri));
            }

            if (!CanLoad(uri, string.Empty, Directory.GetCurrentDirectory(), out Uri metadataUri))
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MetadataResources.ErrInvalidUriFormat, uri));
            }

            if (metadataUri.IsFile)
            {
                // the input could be a reference to a list of files specified with wildcards, let's check.
                var fileInfoList = MetadataFileNameManager.ResolveFiles(metadataUri.LocalPath);

                // when only the wsdl file is specified, we need to resolve any schema references.
                _resolveExternalDocs = fileInfoList.Length == 1;
                this.metadataSourceFiles.AddRange(fileInfoList.Select(fi => new Uri(fi.FullName, UriKind.Absolute)));
            }
            else
            {
                _resolveExternalDocs   = true;
                this.MetadataSourceUrl = metadataUri;
            }
        }
        private MetadataFileInfo AddSchema(XmlSchema schema)
        {
            MetadataFileInfo metadataFileInfo = null;

            if (schema != null && !this.MetadataFiles.Any(mi => mi.Metadata == schema) /*&& schema.Items.Count > 0*/)
            {
                var sourceUrl = schema.SourceUri;
                var filePath  = AddFilePath(schema.SourceUri, schema.TargetNamespace, ".xsd");

                schema.SourceUri = Path.GetFileName(filePath);
                metadataFileInfo = new SchemaFileInfo(schema, filePath, sourceUrl, schema.Write);
                this.MetadataFiles.Add(metadataFileInfo);

                var unresolvedRefs = UnresolvedReferences.Where(u =>
                                                                (MetadataFileNameManager.UriEqual(u.SchemaExternal?.SchemaLocation, sourceUrl) ||
                                                                 (!string.IsNullOrEmpty(u.Namespace) && u.Namespace == schema.TargetNamespace))).ToList();

                foreach (var unresolvedRef in unresolvedRefs)
                {
                    unresolvedRef.SchemaExternal.SchemaLocation = schema.SourceUri;
                    UnresolvedReferences.Remove(unresolvedRef);
                }
            }
            return(metadataFileInfo);
        }
 private bool AddUnresolvedSchemaRefs(XmlNS.Schema.XmlSchema schema)
 {
     if (schema != null)
     {
         foreach (XmlNS.Schema.XmlSchemaExternal schemaExternal in schema.Includes)
         {
             if (!this.UnresolvedReferences.Any(r => r.SchemaExternal == schemaExternal))
             {
                 if (!string.IsNullOrEmpty(schemaExternal.SchemaLocation))
                 {
                     schemaExternal.SchemaLocation = MetadataFileNameManager.GetComposedUri(schema.SourceUri, schemaExternal.SchemaLocation);
                     UnresolvedReferences.Add(new UnresolvedUri {
                         Schema = schema, SchemaExternal = schemaExternal
                     });
                 }
                 else if (schemaExternal.Schema == null)
                 {
                     // the MetadataExchangeClient when using MEX protocol downloads wsdl-embedded schemas separately,
                     // need to gather namespace-only imports (which are valid w/o any schema) to be able to connect
                     // the docs if it is the case.
                     var schemaImport = schemaExternal as XmlNS.Schema.XmlSchemaImport;
                     if (schemaImport != null && !string.IsNullOrEmpty(schemaImport.Namespace))
                     {
                         UnresolvedReferences.Add(new UnresolvedUri {
                             Schema = schema, SchemaExternal = schemaExternal, Namespace = schemaImport.Namespace
                         });
                     }
                 }
             }
         }
         return(true);
     }
     return(false);
 }
        /// <summary>
        /// </summary>
        /// <param name="metadataFiles">A collection containing the location of wsdl/schema documents to load service metadata from.</param>
        /// <param name="resolveExternalDocuments">if true, WSDL imports and XmlSchema Includes will be attempted to be resolved.</param>
        /// <param name="httpCredentialsProvider"></param>
        /// <param name="clientCertificatesProvider"></param>
        /// <param name="serverCertificateValidationProvider"></param>
        public MetadataDocumentLoader(IEnumerable <string> metadataFiles, bool resolveExternalDocuments, IHttpCredentialsProvider httpCredentialsProvider, IClientCertificateProvider clientCertificatesProvider, IServerCertificateValidationProvider serverCertificateValidationProvider)
        {
            _httpCredentialsProvider             = httpCredentialsProvider;
            _clientCertificatesProvider          = clientCertificatesProvider;
            _serverCertificateValidationProvider = serverCertificateValidationProvider;

            if (metadataFiles == null)
            {
                throw new ArgumentNullException(nameof(metadataFiles));
            }

            foreach (var uri in metadataFiles)
            {
                if (!CanLoad(uri, string.Empty, Directory.GetCurrentDirectory(), out Uri metadataUri))
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MetadataResources.ErrInvalidUriFormat, uri));
                }

                if (!metadataUri.IsFile)
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MetadataResources.ErrUrlNotAllowedOnMultipleInputsFormat, metadataUri));
                }

                var fileInfoList = MetadataFileNameManager.ResolveFiles(metadataUri.LocalPath);
                this.metadataSourceFiles.AddRange(fileInfoList.Select(fi => new Uri(fi.FullName, UriKind.Absolute)));
            }

            _resolveExternalDocs = resolveExternalDocuments;
        }
        /// <summary>
        /// Attempts to resolve a metadata document in disk (wsdl/schema file).
        /// </summary>
        /// <param name="schemaUri">The resolved URI for the specified schema file.</param>
        /// <param name="schemaLocation">The original location of the schema file, this could be a relative path.</param>
        /// <param name="basePath">The wsdl docs path in disk.</param>
        /// <param name="specNamespace">The namespace for the file document (schema/wsdl)</param>
        /// <param name="extension">The extension of the document file in disk (.xsd/.wsdl)</param>
        /// <param name="schemaFile">The resolved URI for the document file.</param>
        /// <returns>True, if the file exists; false otherwise.</returns>
        private bool TryGetExistingSchemaFile(Uri schemaUri, string schemaLocation, string basePath, string specNamespace, string extension, out Uri schemaFile)
        {
            // Try to get the file name.

            string fullFileName = schemaUri.IsFile ? schemaUri.LocalPath : schemaLocation;

            schemaFile = null;

            // check if the file has already been downloaded using some heuristics.

            if (!File.Exists(fullFileName))
            {
                if (schemaUri.Segments.Length > 0)
                {
                    // the URI may contain the file name.
                    fullFileName = Path.Combine(basePath, schemaUri.Segments[schemaUri.Segments.Length - 1]);
                }

                if (!File.Exists(fullFileName) && !string.IsNullOrWhiteSpace(specNamespace))
                {
                    // reconstruct the local file name for the remote location (assuming files downloaded by MetadataDocumentSaver):
                    // <xsd:import schemaLocation="http://serverhost/servcicename.svc?xsd=xsd0" namespace="http://tempuri.org/" />
                    // observe that schema include specs are not processed because on download they are made part of the container schema (must belong to the same namespace).
                    // <xsd:include schemaLocation="xsd1.xsd" />
                    fullFileName = MetadataFileNameManager.GetFilePathFromNamespace(basePath, specNamespace, extension);
                }

                if (!File.Exists(fullFileName) && !Path.IsPathRooted(schemaLocation))
                {
                    fullFileName = Path.Combine(basePath, schemaLocation);

                    if (!File.Exists(fullFileName))
                    {
                        fullFileName = Path.Combine(basePath, Path.GetFileName(schemaLocation));
                    }
                }
            }

            if (File.Exists(fullFileName))
            {
                Uri.TryCreate(fullFileName, UriKind.Absolute, out schemaFile);
            }

            return(schemaFile != null);
        }
        private async Task LoadAsync(string uri, string baseUrl, string basePath, CancellationToken cancellationToken)
        {
            if (CanLoad(uri, baseUrl, basePath, out Uri serviceUri))
            {
                if (serviceUri.Scheme == MetadataConstants.Uri.UriSchemeFile)
                {
                    var fileInfoList = MetadataFileNameManager.ResolveFiles(serviceUri.LocalPath);
                    foreach (var fileInfo in fileInfoList)
                    {
                        if (!IsUriProcessed(fileInfo.FullName))
                        {
                            using (var fileStream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                await LoadFromStreamAsync(fileStream, fileInfo.FullName, fileInfo.DirectoryName, cancellationToken).ConfigureAwait(false);
                            }
                        }
                    }
                }
                else
                {
                    if (!IsUriProcessed(serviceUri.AbsoluteUri))
                    {
                        // Clone providers as they may be in use for a different URI.
                        MetadataExchangeResolver metadataExchangeResolver = MetadataExchangeResolver.Create(
                            new EndpointAddress(serviceUri),
                            _httpCredentialsProvider?.Clone() as IHttpCredentialsProvider,
                            _clientCertificatesProvider?.Clone() as IClientCertificateProvider,
                            _serverCertificateValidationProvider?.Clone() as IServerCertificateValidationProvider);

                        var metadataSections = await metadataExchangeResolver.ResolveMetadataAsync(cancellationToken).ConfigureAwait(false);

                        _metadataSections.AddRange(metadataSections);
                    }
                }
            }
            else
            {
                throw new MetadataExchangeException(MetadataResources.ErrInvalidUriFormat, uri);
            }
        }
        private MetadataFileInfo AddWsdl(WsdlNS.ServiceDescription wsdl)
        {
            MetadataFileInfo metadataFileInfo = null;

            if (wsdl != null && !this.MetadataFiles.Any(mi => mi.Metadata == wsdl))
            {
                var sourceUrl = wsdl.RetrievalUrl;
                var filePath  = AddFilePath(wsdl.RetrievalUrl, wsdl.TargetNamespace, ".wsdl");

                wsdl.RetrievalUrl = Path.GetFileName(filePath);
                metadataFileInfo  = new WsdlFileInfo(wsdl, filePath, sourceUrl, wsdl.Write);
                this.MetadataFiles.Add(metadataFileInfo);

                var unresolvedRefs = UnresolvedReferences.Where(u => MetadataFileNameManager.UriEqual(u.WsdlImport?.Location, sourceUrl)).ToList();
                foreach (var unresolvedRef in unresolvedRefs)
                {
                    unresolvedRef.WsdlImport.Location = wsdl.RetrievalUrl;
                    UnresolvedReferences.Remove(unresolvedRef);
                }
            }
            return(metadataFileInfo);
        }
        private bool AddUnresolvedWsdlRefs(WsdlNS.ServiceDescription wsdl)
        {
            if (wsdl != null)
            {
                foreach (WsdlNS.Import import in wsdl.Imports)
                {
                    if (!string.IsNullOrEmpty(import.Location) && !this.UnresolvedReferences.Any(r => r.WsdlImport == import))
                    {
                        import.Location = MetadataFileNameManager.GetComposedUri(wsdl.RetrievalUrl, import.Location);
                        UnresolvedReferences.Add(new UnresolvedUri {
                            WsdlImport = import, Wsdl = wsdl
                        });
                    }
                }

                foreach (XmlNS.Schema.XmlSchema schema in wsdl.Types.Schemas)
                {
                    AddUnresolvedSchemaRefs(schema);
                }
                return(true);
            }
            return(false);
        }
示例#10
0
            public override bool Equals(object obj)
            {
                UnresolvedUri other = obj as UnresolvedUri;

                return(other != null && MetadataFileNameManager.UriEqual(this.Uri, other.Uri));
            }
示例#11
0
        private void AddMetadataFiles(IEnumerable <MetadataSection> documents)
        {
            if (documents == null)
            {
                throw new ArgumentNullException(nameof(documents));
            }

            // prepopulate schema/wsdl includes/imports so references can be resolved/updated when resolving document paths.
            foreach (var doc in documents)
            {
                if (!AddUnresolvedSchemaRefs(doc.Metadata as XmlNS.Schema.XmlSchema))
                {
                    AddUnresolvedWsdlRefs(doc.Metadata as WsdlNS.ServiceDescription);
                }
            }

            // compute document paths.
            foreach (var doc in documents)
            {
                if (AddWsdl(doc.Metadata as WsdlNS.ServiceDescription) == null)
                {
                    if (AddSchema(doc.Metadata as XmlNS.Schema.XmlSchema) == null)
                    {
                        if (AddXmlDocument(doc.Metadata as XmlNS.XmlElement, doc.Dialect) == null)
                        {
#if DEBUG
                            string typeName = doc.Metadata.GetType().ToString();
                            Debug.Fail("Unknown metadata found: " + typeName);
#endif
                        }
                    }
                }
            }

            for (int idx = UnresolvedReferences.Count - 1; idx >= 0; idx--)
            {
                var unresolvedRef = UnresolvedReferences[idx];

                if (unresolvedRef.Namespace != null)
                {
                    // remove namespace-only schema references as they are still valid
                    UnresolvedReferences.RemoveAt(idx);
                }
                else
                {
                    // remove schema references for which multiple files are resolved (wildcards).
                    var location = unresolvedRef.WsdlImport != null ? unresolvedRef.WsdlImport.Location : unresolvedRef.SchemaExternal?.SchemaLocation;

                    if (MetadataFileNameManager.TryCreateUri(location, out Uri locationUri) && MetadataFileNameManager.TryResolveFiles(locationUri.LocalPath, out var files))
                    {
                        var missingRefs = files.Where(file => !this.MetadataFiles.Any(metaFile => MetadataFileNameManager.UriEqual(file.FullName, metaFile.SourceUri)));
                        if (missingRefs.Count() == 0)
                        {
                            var updatedLocation = Path.Combine(this.DirectoryPath, Path.GetFileName(location));
                            if (unresolvedRef.WsdlImport != null)
                            {
                                unresolvedRef.WsdlImport.Location = updatedLocation;
                            }
                            else
                            {
                                unresolvedRef.SchemaExternal.SchemaLocation = updatedLocation;
                            }
                            UnresolvedReferences.Remove(unresolvedRef);
                        }
                    }
                }
            }
        }
示例#12
0
 public bool Equals(string otherFilePath)
 {
     return(otherFilePath != null && MetadataFileNameManager.UriEqual(this.FilePath, otherFilePath));
 }
        private static void FixupChameleonSchemas(IEnumerable <MetadataSection> metadataSections)
        {
            // Chameleon schemas are those w/o a target namespace, types from these schemas become part of the namespace of the enclosing schema.

            var documents        = metadataSections.Select((s) => s.Metadata);
            var schemas          = documents.OfType <XmlNS.Schema.XmlSchema>();
            var chameleonSchemas = schemas.Where(s => string.IsNullOrEmpty(s.TargetNamespace));

            foreach (var schema in schemas)
            {
                foreach (XmlNS.Schema.XmlSchemaExternal include in schema.Includes)
                {
                    var chameleonSchema = chameleonSchemas.FirstOrDefault(c =>
                                                                          c != schema && MetadataFileNameManager.UriEqual(MetadataFileNameManager.GetComposedUri(c.SourceUri, null), MetadataFileNameManager.GetComposedUri(schema.SourceUri, include.SchemaLocation)));

                    if (chameleonSchema != null)
                    {
                        include.Schema = chameleonSchema;
                    }
                }
            }
        }