Merge pull request #3389 from lambdageek/bug-43099
[mono.git] / mcs / class / referencesource / System.Web / Compilation / XsdBuildProvider.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="XsdBuildProvider.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>                                                                
5 //------------------------------------------------------------------------------
6
7 namespace System.Web.Compilation {
8
9 using System;
10 using System.IO;
11 using System.Data;
12 using System.Data.Design;
13 using System.Diagnostics.CodeAnalysis;
14 using System.Globalization;
15 using System.Xml;
16 using System.Xml.Schema;
17 using System.Reflection;
18 using System.CodeDom;
19 using System.CodeDom.Compiler;
20 using System.Web.Hosting;
21 using System.Web.Configuration;
22 using System.Collections;
23
24 using Util=System.Web.UI.Util;
25 #if !FEATURE_PAL // FEATURE_PAL does not support System.Data.Design
26 using TypedDataSetGenerator=System.Data.Design.TypedDataSetGenerator;
27 #endif // !FEATURE_PAL 
28
29 [BuildProviderAppliesTo(BuildProviderAppliesTo.Code)]
30 internal class XsdBuildProvider: BuildProvider {
31
32     [SuppressMessage("Microsoft.Security", "MSEC1207:UseXmlReaderForLoad", Justification = "Developer-controlled .xsd files in application directory are implicitly trusted by ASP.Net.")]
33     [SuppressMessage("Microsoft.Security.Xml", "CA3056:UseXmlReaderForLoad", Justification = "Developer-controlled .xml files in application directory are implicitly trusted by ASP.Net.")]
34     public override void GenerateCode(AssemblyBuilder assemblyBuilder)  {
35 #if !FEATURE_PAL // FEATURE_PAL does not support System.Data.Design
36         // Get the namespace that we will use
37         string ns = Util.GetNamespaceFromVirtualPath(VirtualPathObject);
38
39         // We need to use XmlDocument to parse the xsd file is order to open it with the
40         // correct encoding (VSWhidbey 566286)
41         XmlDocument doc = new XmlDocument();
42         using (Stream stream = OpenStream()) {
43             doc.Load(stream);
44         }
45         String content = doc.OuterXml;
46
47         // Generate a CodeCompileUnit from the dataset
48         CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
49
50         CodeNamespace codeNamespace = new CodeNamespace(ns);
51         codeCompileUnit.Namespaces.Add(codeNamespace);
52
53         // Devdiv 18365, Dev10 bug 444516 
54         // Call a different Generate method if compiler version is v3.5 or above
55         bool isVer35OrAbove = CompilationUtil.IsCompilerVersion35OrAbove(assemblyBuilder.CodeDomProvider.GetType());
56
57         if (isVer35OrAbove) {
58             TypedDataSetGenerator.GenerateOption generateOptions = TypedDataSetGenerator.GenerateOption.None;
59             generateOptions |= TypedDataSetGenerator.GenerateOption.HierarchicalUpdate;
60             generateOptions |= TypedDataSetGenerator.GenerateOption.LinqOverTypedDatasets;
61             Hashtable customDBProviders = null;
62             TypedDataSetGenerator.Generate(content, codeCompileUnit, codeNamespace, assemblyBuilder.CodeDomProvider, customDBProviders, generateOptions);
63         }
64         else {
65             TypedDataSetGenerator.Generate(content, codeCompileUnit, codeNamespace, assemblyBuilder.CodeDomProvider);
66         }
67
68         // Add all the assembly references needed by the generated code
69         if (TypedDataSetGenerator.ReferencedAssemblies != null) {
70             var isVer35 = CompilationUtil.IsCompilerVersion35(assemblyBuilder.CodeDomProvider.GetType());
71             foreach (Assembly a in TypedDataSetGenerator.ReferencedAssemblies) {
72                 
73                 if (isVer35) {
74                     var aName = a.GetName();
75                     if (aName.Name == "System.Data.DataSetExtensions") {
76                         // Dev10 Bug 861688 - We need to specify v3.5 version so that the build system knows to use the v3.5 version
77                         // because the loaded assembly here is always v4.0
78                         aName.Version = new Version(3, 5, 0, 0);
79                         CompilationSection.RecordAssembly(aName.FullName, a);
80                     }
81                 }
82                 assemblyBuilder.AddAssemblyReference(a);
83             }
84         }
85         
86
87         // Add the CodeCompileUnit to the compilation
88         assemblyBuilder.AddCodeCompileUnit(this, codeCompileUnit);
89 #else // !FEATURE_PAL 
90         throw new NotImplementedException("System.Data.Design - ROTORTODO");
91 #endif // !FEATURE_PAL 
92     }
93 }
94 }