511 lines
24 KiB
C#
511 lines
24 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="BrowserCapabilitiesCompiler.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
namespace System.Web.Compilation {
|
||
|
|
||
|
using System;
|
||
|
using System.CodeDom;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Specialized;
|
||
|
using System.Configuration;
|
||
|
using System.CodeDom.Compiler;
|
||
|
using System.Diagnostics.CodeAnalysis;
|
||
|
using System.Globalization;
|
||
|
using System.IO;
|
||
|
using System.Reflection;
|
||
|
using System.Security;
|
||
|
using System.Security.Permissions;
|
||
|
using System.Web.Configuration;
|
||
|
using System.Web.Hosting;
|
||
|
using System.Web.Util;
|
||
|
using System.Web.UI;
|
||
|
using System.Xml;
|
||
|
|
||
|
static class BrowserCapabilitiesCompiler {
|
||
|
|
||
|
internal static readonly VirtualPath AppBrowsersVirtualDir =
|
||
|
HttpRuntime.AppDomainAppVirtualPathObject.SimpleCombineWithDir(HttpRuntime.BrowsersDirectoryName);
|
||
|
|
||
|
private const string browerCapabilitiesTypeName = "BrowserCapabilities";
|
||
|
private const string browerCapabilitiesCacheKey = "__browserCapabilitiesCompiler";
|
||
|
|
||
|
private static Type _browserCapabilitiesFactoryBaseType;
|
||
|
|
||
|
private static BrowserCapabilitiesFactoryBase _browserCapabilitiesFactoryBaseInstance;
|
||
|
private static object _lockObject = new object();
|
||
|
internal static Assembly AspBrowserCapsFactoryAssembly { get; set; }
|
||
|
|
||
|
static BrowserCapabilitiesCompiler() {
|
||
|
Assembly assembly = null;
|
||
|
String publicKeyToken = BrowserCapabilitiesCodeGenerator.BrowserCapAssemblyPublicKeyToken;
|
||
|
|
||
|
// If the token file cannot be found, do not load the assembly.
|
||
|
if (publicKeyToken != null) {
|
||
|
try {
|
||
|
string version;
|
||
|
|
||
|
// If we are targeting previous versions, try loading the 2.0 version of ASP.BrowserCapsFactory
|
||
|
// (Dev10 bug 795509)
|
||
|
if (MultiTargetingUtil.IsTargetFramework40OrAbove) {
|
||
|
version = ThisAssembly.Version;
|
||
|
} else {
|
||
|
version = "2.0.0.0";
|
||
|
}
|
||
|
assembly = Assembly.Load("ASP.BrowserCapsFactory, Version=" + version + ", Culture=neutral, PublicKeyToken=" + publicKeyToken);
|
||
|
AspBrowserCapsFactoryAssembly = assembly;
|
||
|
}
|
||
|
catch (FileNotFoundException) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// fallback when assembly cannot be found.
|
||
|
if((assembly == null) || (!(assembly.GlobalAssemblyCache))) {
|
||
|
_browserCapabilitiesFactoryBaseType = typeof(System.Web.Configuration.BrowserCapabilitiesFactory);
|
||
|
}
|
||
|
else {
|
||
|
_browserCapabilitiesFactoryBaseType = assembly.GetType("ASP.BrowserCapabilitiesFactory", true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static BrowserCapabilitiesFactoryBase BrowserCapabilitiesFactory {
|
||
|
get {
|
||
|
if(_browserCapabilitiesFactoryBaseInstance != null) {
|
||
|
return _browserCapabilitiesFactoryBaseInstance;
|
||
|
}
|
||
|
Type t = GetBrowserCapabilitiesType();
|
||
|
lock(_lockObject) {
|
||
|
if(_browserCapabilitiesFactoryBaseInstance == null) {
|
||
|
if (t != null) {
|
||
|
_browserCapabilitiesFactoryBaseInstance =
|
||
|
(BrowserCapabilitiesFactoryBase)Activator.CreateInstance(t);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return _browserCapabilitiesFactoryBaseInstance;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static Type GetBrowserCapabilitiesFactoryBaseType() {
|
||
|
return _browserCapabilitiesFactoryBaseType;
|
||
|
}
|
||
|
|
||
|
internal static Type GetBrowserCapabilitiesType() {
|
||
|
|
||
|
//Need to assert here to check directories and files
|
||
|
InternalSecurityPermissions.Unrestricted.Assert();
|
||
|
|
||
|
BuildResult result = null;
|
||
|
|
||
|
try {
|
||
|
// Try the cache first, and if it's not there, compile it
|
||
|
result = BuildManager.GetBuildResultFromCache(browerCapabilitiesCacheKey);
|
||
|
if (result == null) {
|
||
|
DateTime utcStart = DateTime.UtcNow;
|
||
|
|
||
|
VirtualDirectory directory = AppBrowsersVirtualDir.GetDirectory();
|
||
|
|
||
|
// first try if app browser dir exists
|
||
|
string physicalDir = HostingEnvironment.MapPathInternal(AppBrowsersVirtualDir);
|
||
|
|
||
|
/* DevDivBugs 173531
|
||
|
* For the App_Browsers scenario, we need to cache the generated browser caps processing
|
||
|
* code. We need to add path dependency on all files so that changes to them will
|
||
|
* invalidate the cache entry and cause recompilation. */
|
||
|
if (directory != null && Directory.Exists(physicalDir)) {
|
||
|
ArrayList browserFileList = new ArrayList();
|
||
|
ArrayList browserFileDependenciesList = new ArrayList();
|
||
|
bool hasCustomCaps = AddBrowserFilesToList(directory, browserFileList, false);
|
||
|
if (hasCustomCaps) {
|
||
|
AddBrowserFilesToList(directory, browserFileDependenciesList, true);
|
||
|
}
|
||
|
else {
|
||
|
browserFileDependenciesList = browserFileList;
|
||
|
}
|
||
|
|
||
|
if (browserFileDependenciesList.Count > 0) {
|
||
|
ApplicationBrowserCapabilitiesBuildProvider buildProvider = new ApplicationBrowserCapabilitiesBuildProvider();
|
||
|
foreach (string virtualPath in browserFileList) {
|
||
|
buildProvider.AddFile(virtualPath);
|
||
|
}
|
||
|
|
||
|
BuildProvidersCompiler bpc = new BuildProvidersCompiler(null /*configPath*/,
|
||
|
BuildManager.GenerateRandomAssemblyName(BuildManager.AppBrowserCapAssemblyNamePrefix));
|
||
|
|
||
|
bpc.SetBuildProviders(new SingleObjectCollection(buildProvider));
|
||
|
CompilerResults results = bpc.PerformBuild();
|
||
|
Assembly assembly = results.CompiledAssembly;
|
||
|
// Get the type we want from the assembly
|
||
|
Type t = assembly.GetType(
|
||
|
BaseCodeDomTreeGenerator.defaultNamespace + "." + ApplicationBrowserCapabilitiesCodeGenerator.FactoryTypeName);
|
||
|
// Cache it for next time
|
||
|
result = new BuildResultCompiledType(t);
|
||
|
result.VirtualPath = AppBrowsersVirtualDir;
|
||
|
result.AddVirtualPathDependencies(browserFileDependenciesList);
|
||
|
|
||
|
BuildManager.CacheBuildResult(browerCapabilitiesCacheKey, result, utcStart);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
finally {
|
||
|
CodeAccessPermission.RevertAssert();
|
||
|
}
|
||
|
|
||
|
// Simply return the global factory type.
|
||
|
if (result == null)
|
||
|
return _browserCapabilitiesFactoryBaseType;
|
||
|
|
||
|
// Return the compiled type
|
||
|
return ((BuildResultCompiledType)result).ResultType;
|
||
|
}
|
||
|
|
||
|
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands",
|
||
|
Justification="Warning was suppressed for previous version of API (different overload) in FxCop project file.")]
|
||
|
private static bool AddBrowserFilesToList(
|
||
|
VirtualDirectory directory, IList list, bool doRecurse) {
|
||
|
bool hasCustomCaps = false;
|
||
|
|
||
|
foreach (VirtualFileBase fileBase in directory.Children) {
|
||
|
|
||
|
// Recursive into subdirectories.
|
||
|
if (fileBase.IsDirectory) {
|
||
|
if (doRecurse) {
|
||
|
AddBrowserFilesToList((VirtualDirectory)fileBase, list, true);
|
||
|
}
|
||
|
hasCustomCaps = true;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
string extension = Path.GetExtension(fileBase.Name);
|
||
|
if (StringUtil.EqualsIgnoreCase(extension, ".browser")) {
|
||
|
list.Add(fileBase.VirtualPath);
|
||
|
}
|
||
|
}
|
||
|
return hasCustomCaps;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal class ApplicationBrowserCapabilitiesCodeGenerator : BrowserCapabilitiesCodeGenerator {
|
||
|
internal const string FactoryTypeName = "ApplicationBrowserCapabilitiesFactory";
|
||
|
private OrderedDictionary _browserOverrides;
|
||
|
private OrderedDictionary _defaultBrowserOverrides;
|
||
|
private BrowserCapabilitiesFactoryBase _baseInstance;
|
||
|
private BuildProvider _buildProvider;
|
||
|
|
||
|
internal ApplicationBrowserCapabilitiesCodeGenerator(BuildProvider buildProvider) {
|
||
|
_browserOverrides = new OrderedDictionary();
|
||
|
_defaultBrowserOverrides = new OrderedDictionary();
|
||
|
_buildProvider = buildProvider;
|
||
|
}
|
||
|
|
||
|
internal override bool GenerateOverrides { get { return false; } }
|
||
|
|
||
|
internal override string TypeName {
|
||
|
get {
|
||
|
return FactoryTypeName;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void Create() {
|
||
|
throw new NotSupportedException();
|
||
|
}
|
||
|
|
||
|
private static void AddStringToHashtable(OrderedDictionary table, object key, String content, bool before) {
|
||
|
ArrayList list = (ArrayList)table[key];
|
||
|
if (list == null) {
|
||
|
list = new ArrayList(1);
|
||
|
table[key] = list;
|
||
|
}
|
||
|
|
||
|
if (before) {
|
||
|
list.Insert(0, content);
|
||
|
}
|
||
|
else {
|
||
|
list.Add(content);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static string GetFirstItemFromKey(OrderedDictionary table, object key) {
|
||
|
ArrayList list = (ArrayList)table[key];
|
||
|
|
||
|
if (list != null && list.Count > 0) {
|
||
|
return list[0] as String;
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
[SuppressMessage("Microsoft.Usage", "CA2303:FlagTypeGetHashCode", Justification = "BrowserDefinition is Internal type - okay")]
|
||
|
internal override void HandleUnRecognizedParentElement(BrowserDefinition bd, bool isDefault)
|
||
|
{
|
||
|
// Use the valid type name so we can find the corresponding parent node.
|
||
|
String parentName = bd.ParentName;
|
||
|
int hashKey = bd.GetType().GetHashCode() ^ parentName.GetHashCode();
|
||
|
|
||
|
// Add the refID in front of the list so they gets to be called first.
|
||
|
if (isDefault) {
|
||
|
AddStringToHashtable(_defaultBrowserOverrides, hashKey, bd.Name, bd.IsRefID);
|
||
|
} else {
|
||
|
AddStringToHashtable(_browserOverrides, hashKey, bd.Name, bd.IsRefID);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//generate the code from the parsed BrowserDefinitionTree
|
||
|
//compile it, and install it in the gac
|
||
|
internal void GenerateCode(AssemblyBuilder assemblyBuilder) {
|
||
|
|
||
|
ProcessBrowserFiles(true /*useVirtualPath*/, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString);
|
||
|
ProcessCustomBrowserFiles(true /*useVirtualPath*/, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString);
|
||
|
|
||
|
CodeCompileUnit ccu = new CodeCompileUnit();
|
||
|
|
||
|
Debug.Assert(BrowserTree != null);
|
||
|
ArrayList customTreeRoots = new ArrayList();
|
||
|
for (int i = 0; i < CustomTreeNames.Count; i++) {
|
||
|
customTreeRoots.Add((BrowserDefinition)(((BrowserTree)CustomTreeList[i])[CustomTreeNames[i]]));
|
||
|
}
|
||
|
|
||
|
// namespace ASP
|
||
|
CodeNamespace cnamespace = new CodeNamespace(BaseCodeDomTreeGenerator.defaultNamespace);
|
||
|
//GEN: using System;
|
||
|
cnamespace.Imports.Add(new CodeNamespaceImport("System"));
|
||
|
//GEN: using System.Web;
|
||
|
cnamespace.Imports.Add(new CodeNamespaceImport("System.Web"));
|
||
|
//GEN: using System.Web.Configuration;
|
||
|
cnamespace.Imports.Add(new CodeNamespaceImport("System.Web.Configuration"));
|
||
|
//GEN: using System.Reflection;
|
||
|
cnamespace.Imports.Add(new CodeNamespaceImport("System.Reflection"));
|
||
|
//GEN: class BrowserCapabilitiesFactory
|
||
|
ccu.Namespaces.Add(cnamespace);
|
||
|
|
||
|
Type baseType = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType();
|
||
|
|
||
|
CodeTypeDeclaration factoryType = new CodeTypeDeclaration();
|
||
|
factoryType.Attributes = MemberAttributes.Private;
|
||
|
factoryType.IsClass = true;
|
||
|
factoryType.Name = TypeName;
|
||
|
factoryType.BaseTypes.Add(new CodeTypeReference(baseType));
|
||
|
cnamespace.Types.Add(factoryType);
|
||
|
|
||
|
BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic;
|
||
|
|
||
|
BrowserDefinition bd = null;
|
||
|
//GEN: protected override object ConfigureBrowserCapabilities(NameValueCollection headers, HttpBrowserCapabilities browserCaps)
|
||
|
CodeMemberMethod method = new CodeMemberMethod();
|
||
|
method.Attributes = MemberAttributes.Override | MemberAttributes.Public;
|
||
|
method.ReturnType = new CodeTypeReference(typeof(void));
|
||
|
method.Name = "ConfigureCustomCapabilities";
|
||
|
CodeParameterDeclarationExpression cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
|
||
|
method.Parameters.Add(cpde);
|
||
|
cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps");
|
||
|
method.Parameters.Add(cpde);
|
||
|
factoryType.Members.Add(method);
|
||
|
|
||
|
for (int i = 0; i < customTreeRoots.Count; i++) {
|
||
|
GenerateSingleProcessCall((BrowserDefinition)customTreeRoots[i], method);
|
||
|
}
|
||
|
|
||
|
foreach (DictionaryEntry entry in _browserOverrides) {
|
||
|
object key = entry.Key;
|
||
|
BrowserDefinition firstBrowserDefinition = (BrowserDefinition)BrowserTree[GetFirstItemFromKey(_browserOverrides, key)];
|
||
|
|
||
|
string parentName = firstBrowserDefinition.ParentName;
|
||
|
|
||
|
//
|
||
|
|
||
|
|
||
|
|
||
|
if ((!TargetFrameworkUtil.HasMethod(baseType, parentName + "ProcessBrowsers", flags)) ||
|
||
|
(!TargetFrameworkUtil.HasMethod(baseType, parentName + "ProcessGateways", flags))) {
|
||
|
String parentID = firstBrowserDefinition.ParentID;
|
||
|
|
||
|
if (firstBrowserDefinition != null) {
|
||
|
throw new ConfigurationErrorsException(SR.GetString(SR.Browser_parentID_Not_Found, parentID), firstBrowserDefinition.XmlNode);
|
||
|
} else {
|
||
|
throw new ConfigurationErrorsException(SR.GetString(SR.Browser_parentID_Not_Found, parentID));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool isBrowserDefinition = true;
|
||
|
if (firstBrowserDefinition is GatewayDefinition) {
|
||
|
isBrowserDefinition = false;
|
||
|
}
|
||
|
|
||
|
//GenerateMethodsToOverrideBrowsers
|
||
|
//Gen: protected override void Xxx_ProcessChildBrowsers(bool ignoreApplicationBrowsers, MNameValueCollection headers, HttpBrowserCapabilities browserCaps) ;
|
||
|
|
||
|
string methodName = parentName + (isBrowserDefinition ? "ProcessBrowsers" : "ProcessGateways");
|
||
|
CodeMemberMethod cmm = new CodeMemberMethod();
|
||
|
cmm.Name = methodName;
|
||
|
cmm.ReturnType = new CodeTypeReference(typeof(void));
|
||
|
cmm.Attributes = MemberAttributes.Family | MemberAttributes.Override;
|
||
|
|
||
|
if (isBrowserDefinition) {
|
||
|
cpde = new CodeParameterDeclarationExpression(typeof(bool), BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);
|
||
|
cmm.Parameters.Add(cpde);
|
||
|
}
|
||
|
cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
|
||
|
cmm.Parameters.Add(cpde);
|
||
|
cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), browserCapsVariable);
|
||
|
cmm.Parameters.Add(cpde);
|
||
|
|
||
|
factoryType.Members.Add(cmm);
|
||
|
|
||
|
ArrayList overrides = (ArrayList)_browserOverrides[key];
|
||
|
CodeStatementCollection statements = cmm.Statements;
|
||
|
|
||
|
bool ignoreApplicationBrowsersVarRefGenerated = false;
|
||
|
|
||
|
foreach (string browserID in overrides) {
|
||
|
bd = (BrowserDefinition)BrowserTree[browserID];
|
||
|
if (bd is GatewayDefinition || bd.IsRefID) {
|
||
|
GenerateSingleProcessCall(bd, cmm);
|
||
|
}
|
||
|
else {
|
||
|
if (!ignoreApplicationBrowsersVarRefGenerated) {
|
||
|
Debug.Assert(isBrowserDefinition);
|
||
|
|
||
|
// Gen: if (ignoreApplicationBrowsers) {
|
||
|
// }
|
||
|
// else {
|
||
|
// ...
|
||
|
// }
|
||
|
CodeConditionStatement istatement = new CodeConditionStatement();
|
||
|
|
||
|
istatement.Condition = new CodeVariableReferenceExpression(BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);
|
||
|
|
||
|
cmm.Statements.Add(istatement);
|
||
|
statements = istatement.FalseStatements;
|
||
|
|
||
|
ignoreApplicationBrowsersVarRefGenerated = true;
|
||
|
}
|
||
|
statements = GenerateTrackedSingleProcessCall(statements, bd, cmm);
|
||
|
if (_baseInstance == null) {
|
||
|
// If we are targeting 4.0 or using the ASP.BrowserCapsFactory assembly generated by
|
||
|
// aspnet_regbrowsers.exe, we can simply just instantiate the type.
|
||
|
// If not, then we need to use the type BrowserCapabilitiesFactory35 that contains code
|
||
|
// from the 2.0 version of BrowserCapabilitiesFactory. This is because "baseType" is the 4.0 type
|
||
|
// that contains the new 4.0 definitions.
|
||
|
// (Dev10 bug 795509)
|
||
|
if (MultiTargetingUtil.IsTargetFramework40OrAbove ||
|
||
|
baseType.Assembly == BrowserCapabilitiesCompiler.AspBrowserCapsFactoryAssembly) {
|
||
|
_baseInstance = (BrowserCapabilitiesFactoryBase)Activator.CreateInstance(baseType);
|
||
|
}
|
||
|
else {
|
||
|
_baseInstance = new BrowserCapabilitiesFactory35();
|
||
|
}
|
||
|
}
|
||
|
int parentDepth = (int)((Triplet)_baseInstance.InternalGetBrowserElements()[parentName]).Third;
|
||
|
AddBrowserToCollectionRecursive(bd, parentDepth + 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
foreach (DictionaryEntry entry in _defaultBrowserOverrides) {
|
||
|
object key = entry.Key;
|
||
|
|
||
|
BrowserDefinition firstDefaultBrowserDefinition = (BrowserDefinition)DefaultTree[GetFirstItemFromKey(_defaultBrowserOverrides, key)];
|
||
|
string parentName = firstDefaultBrowserDefinition.ParentName;
|
||
|
|
||
|
if (baseType.GetMethod("Default" + parentName + "ProcessBrowsers", flags) == null) {
|
||
|
String parentID = firstDefaultBrowserDefinition.ParentID;
|
||
|
if (firstDefaultBrowserDefinition != null) {
|
||
|
throw new ConfigurationErrorsException(SR.GetString(SR.DefaultBrowser_parentID_Not_Found, parentID), firstDefaultBrowserDefinition.XmlNode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
string methodName = "Default" + parentName + "ProcessBrowsers";
|
||
|
CodeMemberMethod cmm = new CodeMemberMethod();
|
||
|
cmm.Name = methodName;
|
||
|
cmm.ReturnType = new CodeTypeReference(typeof(void));
|
||
|
cmm.Attributes = MemberAttributes.Family | MemberAttributes.Override;
|
||
|
cpde = new CodeParameterDeclarationExpression(typeof(bool), BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);
|
||
|
cmm.Parameters.Add(cpde);
|
||
|
cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers");
|
||
|
cmm.Parameters.Add(cpde);
|
||
|
cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), browserCapsVariable);
|
||
|
cmm.Parameters.Add(cpde);
|
||
|
factoryType.Members.Add(cmm);
|
||
|
|
||
|
ArrayList overrides = (ArrayList)_defaultBrowserOverrides[key];
|
||
|
|
||
|
CodeConditionStatement istatement = new CodeConditionStatement();
|
||
|
istatement.Condition = new CodeVariableReferenceExpression(BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName);
|
||
|
|
||
|
cmm.Statements.Add(istatement);
|
||
|
CodeStatementCollection statements = istatement.FalseStatements;
|
||
|
|
||
|
foreach(string browserID in overrides) {
|
||
|
bd = (BrowserDefinition)DefaultTree[browserID];
|
||
|
Debug.Assert(!(bd is GatewayDefinition));
|
||
|
|
||
|
if(bd.IsRefID) {
|
||
|
GenerateSingleProcessCall(bd, cmm, "Default");
|
||
|
}
|
||
|
else {
|
||
|
statements = GenerateTrackedSingleProcessCall(statements, bd, cmm, "Default");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Generate process method for the browser elements
|
||
|
foreach (DictionaryEntry entry in BrowserTree) {
|
||
|
bd = entry.Value as BrowserDefinition;
|
||
|
Debug.Assert(bd != null);
|
||
|
GenerateProcessMethod(bd, factoryType);
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < customTreeRoots.Count; i++) {
|
||
|
foreach (DictionaryEntry entry in (BrowserTree)CustomTreeList[i]) {
|
||
|
bd = entry.Value as BrowserDefinition;
|
||
|
Debug.Assert(bd != null);
|
||
|
GenerateProcessMethod(bd, factoryType);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Generate process method for the default browser elements
|
||
|
foreach (DictionaryEntry entry in DefaultTree) {
|
||
|
bd = entry.Value as BrowserDefinition;
|
||
|
Debug.Assert(bd != null);
|
||
|
GenerateProcessMethod(bd, factoryType, "Default");
|
||
|
}
|
||
|
GenerateOverrideMatchedHeaders(factoryType);
|
||
|
GenerateOverrideBrowserElements(factoryType);
|
||
|
|
||
|
Assembly assembly = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType().Assembly;
|
||
|
assemblyBuilder.AddAssemblyReference(assembly, ccu);
|
||
|
assemblyBuilder.AddCodeCompileUnit(_buildProvider, ccu);
|
||
|
}
|
||
|
|
||
|
internal override void ProcessBrowserNode(XmlNode node, BrowserTree browserTree) {
|
||
|
if (node.Name == "defaultBrowser") {
|
||
|
throw new ConfigurationErrorsException(SR.GetString(SR.Browser_Not_Allowed_InAppLevel, node.Name), node);
|
||
|
}
|
||
|
|
||
|
base.ProcessBrowserNode(node, browserTree);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal class ApplicationBrowserCapabilitiesBuildProvider : BuildProvider {
|
||
|
|
||
|
private ApplicationBrowserCapabilitiesCodeGenerator _codeGenerator;
|
||
|
|
||
|
internal ApplicationBrowserCapabilitiesBuildProvider() {
|
||
|
_codeGenerator = new ApplicationBrowserCapabilitiesCodeGenerator(this);
|
||
|
}
|
||
|
|
||
|
internal void AddFile(string virtualPath) {
|
||
|
String filePath = HostingEnvironment.MapPathInternal(virtualPath);
|
||
|
_codeGenerator.AddFile(filePath);
|
||
|
}
|
||
|
|
||
|
public override void GenerateCode(AssemblyBuilder assemblyBuilder) {
|
||
|
_codeGenerator.GenerateCode(assemblyBuilder);
|
||
|
}
|
||
|
}
|
||
|
}
|