Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / System.Data.Entity.Design / System / Data / Entity / Design / EntityDesignerUtils.cs
1 //---------------------------------------------------------------------
2 // <copyright file="EntityDesignerUtils.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner       [....]
7 // @backupOwner [....]
8 //---------------------------------------------------------------------
9
10 using System.IO;
11 using System.Text;
12 using System.Xml;
13 using System.Data.Metadata.Edm;
14 using System.Data.Mapping;
15
16 namespace System.Data.Entity.Design
17 {
18     internal static class EntityDesignerUtils
19     {
20         internal const string EdmxRootElementName = "Edmx";
21         internal const string EdmxNamespaceUriV1 = "http://schemas.microsoft.com/ado/2007/06/edmx";
22         internal const string EdmxNamespaceUriV2 = "http://schemas.microsoft.com/ado/2008/10/edmx";
23         internal const string EdmxNamespaceUriV3 = "http://schemas.microsoft.com/ado/2009/11/edmx";
24
25         private static readonly EFNamespaceSet v1Namespaces = new EFNamespaceSet
26                                         { 
27                                             Edmx = EdmxNamespaceUriV1,
28                                             Csdl = XmlConstants.ModelNamespace_1,
29                                             Msl =  StorageMslConstructs.NamespaceUriV1,
30                                             Ssdl = XmlConstants.TargetNamespace_1,
31                                         };
32         private static readonly EFNamespaceSet v2Namespaces = new EFNamespaceSet
33                                         { 
34                                             Edmx = EdmxNamespaceUriV2,
35                                             Csdl = XmlConstants.ModelNamespace_2,
36                                             Msl =  StorageMslConstructs.NamespaceUriV2,
37                                             Ssdl = XmlConstants.TargetNamespace_2,
38                                         };
39         private static readonly EFNamespaceSet v3Namespaces = new EFNamespaceSet
40                                         {
41                                             Edmx = EdmxNamespaceUriV3,
42                                             Csdl = XmlConstants.ModelNamespace_3,
43                                             Msl = StorageMslConstructs.NamespaceUriV3,
44                                             Ssdl = XmlConstants.TargetNamespace_3,
45                                         };
46         internal static readonly string _edmxFileExtension = ".edmx";
47
48         /// <summary>
49         /// Extract the Conceptual, Mapping and Storage nodes from an EDMX input streams, and extract the value of the metadataArtifactProcessing property.
50         /// </summary>
51         /// <param name="edmxInputStream"></param>
52         /// <param name="conceptualSchemaNode"></param>
53         /// <param name="mappingNode"></param>
54         /// <param name="storageSchemaNode"></param>
55         ///
56         internal static void ExtractConceptualMappingAndStorageNodes(StreamReader edmxInputStream,
57             out XmlElement conceptualSchemaNode, out XmlElement mappingNode, out XmlElement storageSchemaNode, out string metadataArtifactProcessingValue)
58         {
59             // load up an XML document representing the edmx file
60             XmlDocument xmlDocument = new XmlDocument();
61             using (var reader = XmlReader.Create(edmxInputStream))
62             {
63                 xmlDocument.Load(reader);
64             }
65
66             EFNamespaceSet set = v3Namespaces;
67             if (xmlDocument.DocumentElement.NamespaceURI == v2Namespaces.Edmx)
68             {
69                 set = v2Namespaces;
70             }
71             else if (xmlDocument.DocumentElement.NamespaceURI == v1Namespaces.Edmx)
72             {
73                 set = v1Namespaces;
74             }
75
76             XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDocument.NameTable);
77             nsMgr.AddNamespace("edmx", set.Edmx);
78             nsMgr.AddNamespace("edm", set.Csdl);
79             nsMgr.AddNamespace("ssdl", set.Ssdl);
80             nsMgr.AddNamespace("map", set.Msl);
81
82             // find the ConceptualModel Schema node
83             conceptualSchemaNode = (XmlElement)xmlDocument.SelectSingleNode(
84                 "/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/edm:Schema", nsMgr);
85
86             // find the StorageModel Schema node
87             storageSchemaNode = (XmlElement)xmlDocument.SelectSingleNode(
88                 "/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema", nsMgr);
89
90             // find the Mapping node
91             mappingNode = (XmlElement)xmlDocument.SelectSingleNode(
92                 "/edmx:Edmx/edmx:Runtime/edmx:Mappings/map:Mapping", nsMgr);
93
94             // find the Connection node
95
96             metadataArtifactProcessingValue = String.Empty;
97             XmlNodeList connectionProperties = xmlDocument.SelectNodes(
98                 "/edmx:Edmx/edmx:Designer/edmx:Connection/edmx:DesignerInfoPropertySet/edmx:DesignerProperty", nsMgr);
99             if (connectionProperties != null)
100             {
101                 foreach (XmlNode propertyNode in connectionProperties)
102                 {
103                     foreach (XmlAttribute a in propertyNode.Attributes)
104                     {
105                         // treat attribute names case-sensitive (since it is xml), but attribute value case-insensitive to be accommodating .
106                         if (a.Name.Equals("Name", StringComparison.Ordinal) && a.Value.Equals("MetadataArtifactProcessing", StringComparison.OrdinalIgnoreCase))
107                         {
108                             foreach (XmlAttribute a2 in propertyNode.Attributes)
109                             {
110                                 if (a2.Name.Equals("Value", StringComparison.Ordinal))
111                                 {
112                                     metadataArtifactProcessingValue = a2.Value;
113                                     break;
114                                 }
115                             }
116                         }
117                     }
118                 }
119             }
120         }
121
122         // utility method to ensure an XmlElement (containing the C, M or S element
123         // from the Edmx file) is sent out to a stream in the same format
124         internal static void OutputXmlElementToStream(XmlElement xmlElement, Stream stream)
125         {
126             XmlWriterSettings settings = new XmlWriterSettings();
127             settings.Encoding = Encoding.UTF8;
128             settings.Indent = true;
129
130             // set up output document
131             XmlDocument outputXmlDoc = new XmlDocument();
132             XmlNode importedElement = outputXmlDoc.ImportNode(xmlElement, true);
133             outputXmlDoc.AppendChild(importedElement);
134
135             // write out XmlDocument
136             XmlWriter writer = null;
137             try
138             {
139                 writer = XmlWriter.Create(stream, settings);
140                 outputXmlDoc.WriteTo(writer);
141             }
142             finally
143             {
144                 if (writer != null) { writer.Close(); }
145             }
146         }
147
148         private struct EFNamespaceSet
149         {
150             public string Edmx;
151             public string Csdl;
152             public string Msl;
153             public string Ssdl;
154         }
155     }
156 }