1 //---------------------------------------------------------------------
2 // <copyright file="MetadataUtil.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System.Collections.Generic;
12 using System.Data.SqlClient;
14 using System.Data.Metadata.Edm;
16 using System.Data.Common;
17 using System.Reflection;
19 using System.Diagnostics;
20 using System.Collections;
21 using System.Globalization;
24 namespace System.Data.Entity.Design.Common
26 internal static class MetadataUtil
28 private const string s_defaultDelimiter = ", ";
30 internal static bool IsStoreType(GlobalItem item)
32 return item.DataSpace == DataSpace.SSpace;
35 internal static DbProviderServices GetProviderServices(DbProviderFactory factory)
37 EDesignUtil.CheckArgumentNull(factory, "factory");
39 // Special case SQL client so that it will work with System.Data from .NET 4.0 even without
40 // a binding redirect.
41 if (factory is SqlClientFactory)
43 return SqlProviderServices.Instance;
46 IServiceProvider serviceProvider = factory as IServiceProvider;
47 if (serviceProvider == null)
49 throw MetadataUtil.ProviderIncompatible(System.Data.Entity.Design.Strings.EntityClient_DoesNotImplementIServiceProvider(
50 factory.GetType().ToString()));
53 DbProviderServices providerServices = serviceProvider.GetService(typeof(DbProviderServices)) as DbProviderServices;
54 if (providerServices == null)
56 throw MetadataUtil.ProviderIncompatible(
57 System.Data.Entity.Design.Strings.EntityClient_ReturnedNullOnProviderMethod(
59 factory.GetType().ToString()));
61 return providerServices;
64 static internal ProviderIncompatibleException ProviderIncompatible(string error)
66 ProviderIncompatibleException e = new ProviderIncompatibleException(error);
71 /// Check if all the SchemaErrors have the serverity of SchemaErrorSeverity.Warning
73 /// <param name="schemaErrors"></param>
74 /// <returns></returns>
75 internal static bool CheckIfAllErrorsAreWarnings(IList<EdmSchemaError> schemaErrors)
77 int length = schemaErrors.Count;
78 for (int i = 0; i < length; ++i)
80 EdmSchemaError error = schemaErrors[i];
81 if (error.Severity != EdmSchemaErrorSeverity.Warning)
90 /// This private static method checks a string to make sure that it is not empty.
91 /// Comparing with String.Empty is not sufficient since a string with nothing
92 /// but white space isn't considered "empty" by that rationale.
94 internal static bool IsNullOrEmptyOrWhiteSpace(string value)
96 return IsNullOrEmptyOrWhiteSpace(value, 0);
99 internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset)
101 // don't use Trim(), which will copy the string, which may be large, just to test for emptyness
102 //return String.IsNullOrEmpty(value) || String.IsNullOrEmpty(value.Trim());
105 for (int i = offset; i < value.Length; ++i)
107 if (!Char.IsWhiteSpace(value[i]))
116 // separate implementation from IsNullOrEmptyOrWhiteSpace(string, int) because that one will
117 // pick up the jit optimization to avoid boundary checks and the this won't is unknown (most likely not)
118 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll
119 internal static bool IsNullOrEmptyOrWhiteSpace(string value, int offset, int length)
121 // don't use Trim(), which will copy the string, which may be large, just to test for emptyness
122 //return String.IsNullOrEmpty(value) || String.IsNullOrEmpty(value.Trim());
125 length = Math.Min(value.Length, length);
126 for (int i = offset; i < length; ++i)
128 if (!Char.IsWhiteSpace(value[i]))
137 internal static string MembersToCommaSeparatedString(IEnumerable members)
139 StringBuilder builder = new StringBuilder();
141 MetadataUtil.ToCommaSeparatedString(builder, members);
143 return builder.ToString();
146 internal static void ToCommaSeparatedString(StringBuilder builder, IEnumerable list)
148 ToSeparatedStringPrivate(builder, list, s_defaultDelimiter, string.Empty, false);
151 // effects: Converts the list to a list of strings, sorts its (if
152 // toSort is true) and then converts to a string separated by
153 // "separator" with "nullValue" used for null values.
154 private static void ToSeparatedStringPrivate(StringBuilder stringBuilder, IEnumerable list, string separator,
155 string nullValue, bool toSort)
162 // Get the list of strings first
163 List<string> elementStrings = new List<string>();
164 foreach (object element in list)
167 // Get the element or its default null value
174 str = FormatInvariant("{0}", element);
176 elementStrings.Add(str);
182 elementStrings.Sort(StringComparer.Ordinal);
185 // Now add the strings to the stringBuilder
186 foreach (string str in elementStrings)
188 if (false == isFirst)
190 stringBuilder.Append(separator);
192 stringBuilder.Append(str);
197 internal static string FormatInvariant(string format, params object[] args)
199 Debug.Assert(args.Length > 0, "Formatting utilities must be called with at least one argument");
200 return String.Format(CultureInfo.InvariantCulture, format, args);
204 /// replace troublesome xml characters with equivalent entities
206 /// <param name="text">text that make have characters troublesome in xml</param>
207 /// <returns>text with troublesome characters replaced with equivalent entities</returns>
208 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll
209 internal static string Entityize(string text)
211 if (string.IsNullOrEmpty(text))
214 text = text.Replace("&", "&");
215 text = text.Replace("<", "<").Replace(">", ">");
216 return text.Replace("\'", "'").Replace("\"", """);
219 internal static bool TrySplitExtendedMetadataPropertyName(string name, out string xmlNamespaceUri, out string attributeName)
221 int pos = name.LastIndexOf(':');
222 if (pos < 0 || name.Length <= pos + 1)
224 Debug.Fail("the name is not in the form we expect");
225 xmlNamespaceUri = null;
226 attributeName = null;
230 xmlNamespaceUri = name.Substring(0, pos);
231 attributeName = name.Substring(pos + 1, (name.Length - 1) - pos);
235 static private readonly Type StackOverflowType = typeof(System.StackOverflowException);
236 static private readonly Type OutOfMemoryType = typeof(System.OutOfMemoryException);
237 static private readonly Type ThreadAbortType = typeof(System.Threading.ThreadAbortException);
238 static private readonly Type NullReferenceType = typeof(System.NullReferenceException);
239 static private readonly Type AccessViolationType = typeof(System.AccessViolationException);
240 static private readonly Type SecurityType = typeof(System.Security.SecurityException);
242 internal static bool IsCatchableExceptionType(Exception e)
244 // a 'catchable' exception is defined by what it is not.
245 Debug.Assert(e != null, "Unexpected null exception!");
246 Type type = e.GetType();
248 return ((type != StackOverflowType) &&
249 (type != OutOfMemoryType) &&
250 (type != ThreadAbortType) &&
251 (type != NullReferenceType) &&
252 (type != AccessViolationType) &&
253 !SecurityType.IsAssignableFrom(type));
257 /// Returns the single error message from the list of errors
259 /// <param name="errors"></param>
260 /// <returns></returns>
261 static internal string CombineErrorMessage(IEnumerable<System.Data.Metadata.Edm.EdmSchemaError> errors)
263 Debug.Assert(errors != null);
264 StringBuilder sb = new StringBuilder(System.Environment.NewLine);
266 foreach (System.Data.Metadata.Edm.EdmSchemaError error in errors)
268 //Don't append a new line at the beginning of the messages
271 sb.Append(System.Environment.NewLine);
273 sb.Append(error.ToString());
276 Debug.Assert(count != 0, "Empty Error List");
277 return sb.ToString();
280 internal static void DisposeXmlReaders(IEnumerable<XmlReader> xmlReaders)
282 Debug.Assert(xmlReaders != null);
284 foreach (XmlReader xmlReader in xmlReaders)
286 ((IDisposable)xmlReader).Dispose();
290 internal static bool IsCollectionType(GlobalItem item)
292 return (BuiltInTypeKind.CollectionType == item.BuiltInTypeKind);
295 internal static bool IsComplexType(EdmType type)
297 return (BuiltInTypeKind.ComplexType == type.BuiltInTypeKind);
300 internal static bool IsPrimitiveType(EdmType type)
302 return (BuiltInTypeKind.PrimitiveType == type.BuiltInTypeKind);
305 internal static bool IsEntitySet(EntitySetBase entitySetBase)
307 return BuiltInTypeKind.EntitySet == entitySetBase.BuiltInTypeKind;
310 internal static bool IsValidKeyType(Version entityFrameworkVersion, EdmType type)
312 var primitiveType = type as PrimitiveType;
313 if (primitiveType == null)
317 if (EntityFrameworkVersions.Version1 == entityFrameworkVersion)
319 return primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Binary;
323 // From V2 onwards, Binary key properties are supported
329 /// determines if type is of EnumerationType.
331 /// <param name="type"></param>
332 /// <returns></returns>
333 internal static bool IsEnumerationType(EdmType type)
335 return (BuiltInTypeKind.EnumType == type.BuiltInTypeKind);