1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
//------------------------------------------------------------------------------
// <copyright file="DynamicDiscoSearcher.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.Services.Discovery {
using System;
using System.IO;
using System.Collections;
using System.Diagnostics;
using System.Text;
using System.DirectoryServices;
using System.Web.Services.Configuration;
using System.ComponentModel;
using System.Globalization;
/// <include file='doc\DynamicDiscoSearcher.uex' path='docs/doc[@for="DynamicDiscoSearcher"]/*' />
/// <devdoc>
/// Does a recursive search of subdirectories (physical and virtual) to find stuff to
/// make a disco file from. *.disco files (or whatever the PrimarySearchPattern is) are
/// treated as end-points - recursion stops where they are found.
/// It's a base class for DynamicVirtualDiscoSearcher and DynamicPhysicalDiscoSearcher.
/// </devdoc>
internal abstract class DynamicDiscoSearcher {
protected string origUrl; // original URL to start search
protected string[] excludedUrls; // names relative to starting path
protected string fileToSkipFirst; // name of file to skip on 1st level
protected ArrayList filesFound;
protected DiscoverySearchPattern[] primarySearchPatterns = null;
protected DiscoverySearchPattern[] secondarySearchPatterns = null;
protected DiscoveryDocument discoDoc = new DiscoveryDocument();
protected Hashtable excludedUrlsTable = null;
protected int subDirLevel = 0; // current nested level of subdirectory relative to search root
// -------------------------------------------------------------------------------
internal DynamicDiscoSearcher(string[] excludeUrlsList) {
excludedUrls = excludeUrlsList;
filesFound = new ArrayList();
}
// -------------------------------------------------------------------------------
internal virtual void SearchInit(string fileToSkipAtBegin) {
subDirLevel = 0;
fileToSkipFirst = fileToSkipAtBegin;
}
// -------------------------------------------------------------------------------
protected bool IsExcluded(string url) {
if (excludedUrlsTable == null) {
excludedUrlsTable = new Hashtable();
foreach (string s in excludedUrls) {
Debug.Assert( s != null, "null element in excluded list" );
excludedUrlsTable.Add( MakeAbsExcludedPath(s).ToLower(CultureInfo.InvariantCulture), null);
}
}
return excludedUrlsTable.Contains( url.ToLower(CultureInfo.InvariantCulture) );
}
// -------------------------------------------------------------------------------
internal DiscoveryDocument DiscoveryDocument {
get {
return discoDoc;
}
}
// -------------------------------------------------------------------------------
internal DiscoverySearchPattern[] PrimarySearchPattern {
get {
if (primarySearchPatterns == null) {
// For the primary search the pattern is ".vsdisco"
primarySearchPatterns = new DiscoverySearchPattern[] { new DiscoveryDocumentSearchPattern() };
}
return primarySearchPatterns;
}
}
// -------------------------------------------------------------------------------
internal DiscoverySearchPattern[] SecondarySearchPattern {
get {
if (secondarySearchPatterns == null) {
// ****** Get pattern type from Config (no more needed) *******
// Type[] searchPattern = WebServicesConfiguration.Current.DiscoverySearchPatternTypes;
// secondarySearchPatterns = new DiscoverySearchPattern[searchPattern.Length];
//
// for (int i = 0; i < searchPattern.Length; i++) {
// secondarySearchPatterns[i] = (DiscoverySearchPattern) Activator.CreateInstance(searchPattern[i]);
// }
secondarySearchPatterns = new DiscoverySearchPattern[] { new ContractSearchPattern(),
new DiscoveryDocumentLinksPattern() };
}
return secondarySearchPatterns;
}
}
// -------------------------------------------------------------------------------
// Invokes searching by patterns in current dir. If needed, initiates further search in subdirectories.
protected void ScanDirectory(string directory) {
if ( CompModSwitches.DynamicDiscoverySearcher.TraceVerbose ) Debug.WriteLine( "DynamicDiscoSearcher.ScanDirectory(): directory=" + directory);
if ( IsExcluded(directory) ) // what name is meant here?
return;
bool primaryFound = ScanDirByPattern(directory, true /*primary*/, PrimarySearchPattern);
if (!primaryFound) {
if (!IsVirtualSearch ) {
ScanDirByPattern(directory, false /*secondary*/, SecondarySearchPattern);
} else {
// We restrict second stage of a virtual discovery only to static .disco documents
// We assume that starting directory does not need a second stage
if (subDirLevel != 0) {
DiscoverySearchPattern[] staticDiscoPattern = new DiscoverySearchPattern[] { new DiscoveryDocumentLinksPattern() };
ScanDirByPattern(directory, false /*secondary*/, staticDiscoPattern);
}
}
if ( IsVirtualSearch && subDirLevel > 0 )
return; // stop search in subdir levels deeper than 1 for virtual search
subDirLevel++;
fileToSkipFirst = ""; // do not skip this file on lower levels
SearchSubDirectories(directory); // search deeper (indirect recursion)
subDirLevel--;
}
}
// -------------------------------------------------------------------------------
// Looks in a physical directory for a file matching whatever the configured pattern is.
// Returns: 'true' if primary file has been found (and added to Discovery References).
protected bool ScanDirByPattern(string dir, bool IsPrimary, DiscoverySearchPattern[] patterns) {
DirectoryInfo directory = GetPhysicalDir(dir); // comment here
if ( directory == null )
return false;
if ( CompModSwitches.DynamicDiscoverySearcher.TraceVerbose )
Debug.WriteLine( "= DynamicDiscoSearcher.ScanDirByPattern(): dir=" + dir + " Phys.dir=" + directory.Name);
bool isFileFound = false;
for (int i = 0; i < patterns.Length; i++) {
FileInfo[] files = directory.GetFiles(patterns[i].Pattern); // search in dir
foreach (FileInfo file in files) {
if ((file.Attributes & FileAttributes.Directory) == 0) {
if ( CompModSwitches.DynamicDiscoverySearcher.TraceVerbose ) Debug.WriteLine( "=== DynamicDiscoSearcher.ScanDirByPattern(): file.Name=" + file.Name + " fileToSkipFirst=" + fileToSkipFirst);
// first skip given (i.e. starting) file
if ( String.Compare(file.Name, fileToSkipFirst, StringComparison.OrdinalIgnoreCase) == 0 ) { // ignore case compare
continue;
}
string resultName = MakeResultPath(dir, file.Name);
filesFound.Add( resultName );
discoDoc.References.Add(patterns[i].GetDiscoveryReference(resultName));
isFileFound = true;
}
}
}
return (IsPrimary && isFileFound);
}
// ------------ abstract methods -----------------
/// <include file='doc\DynamicDiscoSearcher.uex' path='docs/doc[@for="DynamicDiscoSearcher.Search"]/*' />
/// <devdoc>
/// Main function. Searches dir recursively for primary (.vsdisco) and seconary (.asmx) files.
/// </devdoc>
internal abstract void Search(string fileToSkipAtBegin);
// Gets phisycal directory info from its virtual or actual name.
protected abstract DirectoryInfo GetPhysicalDir(string dir );
// Search given directory for subdirectories, feasable for further searching.
protected abstract void SearchSubDirectories(string directory);
// Makes result URL found file path from diectory name and short file name.
protected abstract string MakeResultPath(string dirName, string fileName);
// Makes exclusion path absolute for quick comparision on search.
protected abstract string MakeAbsExcludedPath(string pathRelativ);
// 'true' if search isVirtual
protected abstract bool IsVirtualSearch { get; }
}
}
|