PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Accelerator/AcceleratorExtensions.cs

https://bitbucket.org/zgramana/azure-accelerators-project
C# | 516 lines | 269 code | 43 blank | 204 comment | 32 complexity | 0db8932bc3bc8c37519c54afbf7e79d1 MD5 | raw file
Possible License(s): LGPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Security.AccessControl;
  5. using System.Xml;
  6. using System.Xml.Linq;
  7. using System.Text;
  8. using System.Data.Linq;
  9. using System.Linq;
  10. using System.Xml.Serialization;
  11. using System.Xml.Xsl;
  12. namespace Microsoft.WindowsAzure.Accelerator
  13. {
  14. /// <summary>
  15. /// Extension methods for the Accelerators project. (rdm)
  16. /// </summary>
  17. public static class AcceleratorExtensions
  18. {
  19. #region | BASE EXTENSIONS
  20. /// <summary>
  21. /// Returns an element attribute matching the specified name and converted into the expected data type. Handles null values gracefully.
  22. /// </summary>
  23. /// <param name="element">Element whose attributes we are matching by name.</param>
  24. /// <param name="attributeName">Name of the attribute to return the value of the specified type.</param>
  25. /// <returns>Attribute value converted to the specifed type</returns>
  26. public static String GetAttribute(this XElement element, XName attributeName)
  27. {
  28. return element.GetAttribute(attributeName, null);
  29. }
  30. /// <summary>
  31. /// Returns an element attribute matching the specified name and converted into the expected data type. Handles null values gracefully.
  32. /// </summary>
  33. /// <param name="element">Element whose attributes we are matching by name.</param>
  34. /// <param name="attributeName">Name of the attribute to return the value of the specified type.</param>
  35. /// <param name="onEmptyString">The on empty string.</param>
  36. /// <returns>Attribute value converted to the specifed type.</returns>
  37. public static String GetAttribute(this XElement element, XName attributeName, String onEmptyString)
  38. {
  39. return element.OnValid(e => e.Attribute(attributeName).OnValid(a => a.Value)) ?? onEmptyString;
  40. }
  41. /// <summary>
  42. /// Performs the specified action on each element in the sequence handling null gracefully.
  43. /// </summary>
  44. /// <typeparam name="T">The item type.</typeparam>
  45. /// <param name="sequence">Sequence of items.</param>
  46. /// <param name="action">The action to perform.</param>
  47. public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
  48. {
  49. if ( sequence != null )
  50. foreach ( T item in sequence )
  51. action(item);
  52. }
  53. /// <summary>
  54. /// Evaluates the function only when the current object is not null. Provides in-line null value check and continue on valid.
  55. /// </summary>
  56. /// <typeparam name="T">Context value type.</typeparam>
  57. /// <typeparam name="U">Return value type.</typeparam>
  58. /// <param name="value">Context value.</param>
  59. /// <param name="func">Function to perform on non-null context value.</param>
  60. /// <returns>Results of function evaluation.</returns>
  61. public static U OnValid<T,U>(this T value, Func<T, U> func) where T : class
  62. {
  63. return value != null ? func(value) : default(U);
  64. }
  65. /// <summary>
  66. /// Evaluates the action only when the current object is not null. Provides in-line null value check and continue on valid.
  67. /// </summary>
  68. /// <typeparam name="T">Context value type.</typeparam>
  69. /// <param name="value">Context value.</param>
  70. /// <param name="action">Action to perform on non-null context value.</param>
  71. public static void OnValid<T>(this T value, Action<T> action) where T : class
  72. {
  73. if ( value != null ) action(value);
  74. }
  75. /// <summary>
  76. /// Evaluates the function only when value is not null; and then inside a try/catch block. Use OnValid if you wish to handle exceptions.
  77. /// </summary>
  78. /// <typeparam name="T">Context value type.</typeparam>
  79. /// <typeparam name="U">Return value type.</typeparam>
  80. /// <param name="value">Context value.</param>
  81. /// <param name="func">Function to perform on non-null context value.</param>
  82. /// <returns>Results of function evaluation.</returns>
  83. public static void Protect<T>(this T value, Action<T> func) where T : class
  84. {
  85. if ( value != null )
  86. try { func(value); }
  87. catch {}
  88. }
  89. /// <summary>
  90. /// Evaluates the function only when value is not null; and then inside a try/catch block. Use OnValid if you wish to handle exceptions.
  91. /// </summary>
  92. /// <typeparam name="T">Context value type.</typeparam>
  93. /// <typeparam name="U">Return value type.</typeparam>
  94. /// <param name="value">Context value.</param>
  95. /// <param name="func">Function to perform on non-null context value.</param>
  96. /// <returns>Results of function evaluation.</returns>
  97. public static U Protect<T, U>(this T value, Func<T, U> func) where T : class
  98. {
  99. if ( value != null )
  100. try { return func(value); }
  101. catch { }
  102. return default(U);
  103. }
  104. /// <summary>
  105. /// Performs type conversion of the value to the specified type handling nulls with default.
  106. /// </summary>
  107. /// <typeparam name="T">The return type.</typeparam>
  108. /// <param name="value">The object.</param>
  109. /// <returns>Value converted to type T.</returns>
  110. public static T As<T>(this Object value) where T : IConvertible
  111. {
  112. return value == null ? default(T) : (T)Convert.ChangeType(value, typeof(T));
  113. }
  114. /// <summary>
  115. /// Tests if the string is a valid value of the enum type.
  116. /// </summary>
  117. /// <typeparam name="T">The target enum type.</typeparam>
  118. /// <param name="value">The string value to test.</param>
  119. /// <returns>True if the value is a valid member of the enum.</returns>
  120. public static Boolean IsEnum<T>(this String value)
  121. {
  122. return Enum.IsDefined(typeof (T), value);
  123. }
  124. /// <summary>
  125. /// Returns the nullable enum value of the string for the provided enum type; otherwise null.
  126. /// </summary>
  127. /// <typeparam name="T">The target enum type.</typeparam>
  128. /// <param name="value">The string value for conversion.</param>
  129. /// <returns>Nullable of the enum type.</returns>
  130. public static T? ToEnum<T>(this String value) where T : struct
  131. {
  132. return (IsEnum<T>(value) ? (T?) Enum.Parse(typeof (T), value) : null);
  133. }
  134. /// <summary>
  135. /// Selects a descendant heirarchy into a flattened list.
  136. /// </summary>
  137. /// <typeparam name="T">The type.</typeparam>
  138. /// <param name="source">The source.</param>
  139. /// <param name="selector">The selector.</param>
  140. /// <returns>An enumerator.</returns>
  141. public static IEnumerable<T> SelectDeep<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
  142. {
  143. foreach (T item in source)
  144. {
  145. yield return item;
  146. foreach (T subItem in SelectDeep(selector(item), selector))
  147. {
  148. yield return subItem;
  149. }
  150. }
  151. }
  152. /// <summary>
  153. /// Splits as string and returns a list of the specified type.
  154. /// </summary>
  155. /// <typeparam name="T"></typeparam>
  156. /// <param name="value">The string to split.</param>
  157. /// <param name="settingSeparator">The separator.</param>
  158. /// <returns>List of type T.</returns>
  159. public static List<T> SplitToList<T>(this String value, Char[] settingSeparator) where T : IConvertible
  160. {
  161. return value.Split(settingSeparator, StringSplitOptions.RemoveEmptyEntries).Cast<T>().ToList();
  162. }
  163. /// <summary>
  164. /// Splits a string into pairs, then into keys and values, returning a dictionary.
  165. /// </summary>
  166. /// <typeparam name="TKey">The dictionary key type.</typeparam>
  167. /// <typeparam name="TValue">The dictionary value type.</typeparam>
  168. /// <param name="value">The string to splid.</param>
  169. /// <param name="pairsSeparator">The paired items separator.</param>
  170. /// <param name="valuesSeparator">The key value separator for each pair.</param>
  171. /// <returns>Dictionary</returns>
  172. public static Dictionary<TKey, TValue> SplitToDictionary<TKey,TValue>(this String value, Char[] pairsSeparator, Char[] valuesSeparator) where TKey : IConvertible where TValue : IConvertible
  173. {
  174. return value.SplitToList<String>(pairsSeparator).Select(pairs
  175. => pairs.Split(valuesSeparator, StringSplitOptions.RemoveEmptyEntries)).ToDictionary(kvp
  176. => kvp[0].As<TKey>(), kvp => kvp[1].As<TValue>());
  177. }
  178. /// <summary>
  179. /// Creates a string based respresentation of a dictionary.
  180. /// </summary>
  181. /// <typeparam name="TKey">The type of the key.</typeparam>
  182. /// <typeparam name="TValue">The type of the value.</typeparam>
  183. /// <param name="dictionary">The dictionary values.</param>
  184. /// <param name="keyFormat">The key format.</param>
  185. /// <param name="valueFormat">The value format.</param>
  186. /// <returns>
  187. /// String representation of the key value pairs.
  188. /// </returns>
  189. public static String ToString<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, String keyFormat, String valueFormat)
  190. {
  191. if ( dictionary == null )
  192. return null;
  193. return String.Concat(dictionary.Select(x => String.Format("{0}{1}", String.Format(keyFormat, x.Key.ToString()), String.Format(valueFormat, x.Value.ToString()))).ToArray());
  194. }
  195. /// <summary>
  196. /// Creates a string based respresentation of a dictionary.
  197. /// </summary>
  198. /// <param name="dictionary">The dictionary values.</param>
  199. /// <param name="keyFormat">The key format.</param>
  200. /// <param name="valueFormat">The value format.</param>
  201. /// <returns>
  202. /// String representation of the key value pairs.
  203. /// </returns>
  204. public static String ToString(this System.Collections.IDictionary dictionary, String keyFormat, String valueFormat)
  205. {
  206. return dictionary.ToString(keyFormat, valueFormat);
  207. }
  208. /// <summary>
  209. /// Returns a <see cref="System.String"/> that representation of the FileSecurity attributes.
  210. /// </summary>
  211. /// <param name="security">The security.</param>
  212. /// <param name="format">The format - must contain: {0}, {1}, {2} identifiers.</param>
  213. /// <param name="includeExplicit">if set to <c>true</c> [include explicit].</param>
  214. /// <param name="includeInherited">if set to <c>true</c> [include inherited].</param>
  215. /// <returns>
  216. /// A <see cref="System.String"/> that represents this instance.
  217. /// </returns>
  218. public static String ToString(this FileSecurity security, String format, Boolean includeExplicit, Boolean includeInherited)
  219. {
  220. var sb = new StringBuilder();
  221. var accessRules = security.GetAccessRules(includeExplicit, includeInherited, typeof (System.Security.Principal.SecurityIdentifier)).OfType<FileSystemAccessRule>().ToList();
  222. foreach (FileSystemAccessRule rule in accessRules)
  223. {
  224. sb.AppendFormat(format,
  225. String.Format("{{[\"{0}\"], '{1}'}}",
  226. rule.IdentityReference.Value,
  227. rule.AccessControlType),
  228. String.Format("\r\n\t{{\r\n{0}\r\n\t}}\r\n\t{{\r\n{1}\r\n\t}}\r\n",
  229. rule.FileSystemRights.ToString("\t\t{{[\"{0}\"], '{1}'}},\r\n", true),
  230. rule.PropagationFlags.ToString("\t\t{{[\"{0}\"], '{1}'}},\r\n", true)));
  231. }
  232. return sb.ToString();
  233. }
  234. /// <summary>
  235. /// Returns a <see cref="System.String"/> that represents this instance of propagation flags.
  236. /// </summary>
  237. /// <param name="flags">The flags.</param>
  238. /// <param name="kvpFormat">The KVP format.</param>
  239. /// <param name="includeImplicit">if set to <c>true</c> [include implicit].</param>
  240. /// <returns>
  241. /// A <see cref="System.String"/> that represents this instance.
  242. /// </returns>
  243. public static String ToString(this PropagationFlags flags, String kvpFormat, Boolean includeImplicit)
  244. {
  245. var sb = new StringBuilder();
  246. foreach ( PropagationFlags f in Enum.GetValues(typeof(PropagationFlags)) )
  247. {
  248. if ( includeImplicit || ( ( flags & f ) == f ) )
  249. sb.AppendFormat(kvpFormat, f, ( flags & f ) == f);
  250. }
  251. return sb.ToString();
  252. }
  253. /// <summary>
  254. /// Returns a <see cref="System.String"/> that represents this instance of file system rights.
  255. /// </summary>
  256. /// <param name="rights">The rights.</param>
  257. /// <param name="kvpFormat">The KVP format.</param>
  258. /// <param name="includeImplicit">if set to <c>true</c> [include implicit].</param>
  259. /// <returns>
  260. /// A <see cref="System.String"/> that represents this instance.
  261. /// </returns>
  262. public static String ToString(this FileSystemRights rights, String kvpFormat, Boolean includeImplicit)
  263. {
  264. var sb = new StringBuilder();
  265. foreach ( FileSystemRights r in Enum.GetValues(typeof(FileSystemRights)) )
  266. {
  267. if (includeImplicit || ((rights & r) == r))
  268. sb.AppendFormat(kvpFormat, r, ( rights & r ) == r);
  269. }
  270. return sb.ToString();
  271. }
  272. /// <summary>
  273. /// Returns a <see cref="System.String"/> that represents this instance of file attributes.
  274. /// </summary>
  275. /// <param name="attributes">The attributes.</param>
  276. /// <param name="kvpFormat">The KVP format.</param>
  277. /// <param name="includeImplicit">if set to <c>true</c> [include implicit].</param>
  278. /// <returns>
  279. /// A <see cref="System.String"/> that represents this instance.
  280. /// </returns>
  281. public static String ToString(this FileAttributes attributes, String kvpFormat, Boolean includeImplicit)
  282. {
  283. var sb = new StringBuilder();
  284. foreach(FileAttributes a in Enum.GetValues(typeof(FileAttributes)))
  285. {
  286. if (includeImplicit || ((attributes & a) == a))
  287. sb.AppendFormat(kvpFormat, a, (attributes & a) == a);
  288. }
  289. return sb.ToString();
  290. }
  291. /// <summary>
  292. /// Replaces the path char with the separator provided.
  293. /// </summary>
  294. /// <param name="path">The path.</param>
  295. /// <param name="replacePathChar">The replacement char.</param>
  296. /// <remarks>If the supplied path char is a backslash, the assumption is that the path char to be replaced is the forward slash. In all other instances the path char to be replaced is the backslash.</remarks>
  297. /// <returns></returns>
  298. public static String SetPathChar(this String path, Char replacePathChar)
  299. {
  300. if ( String.IsNullOrEmpty(path) )
  301. return path;
  302. return replacePathChar == '\\' ? path.Replace('/', '\\') : path.Replace('\\', replacePathChar);
  303. }
  304. /// <summary>
  305. /// Ensures that this string start with the string provided; otherwise it prepends the string.
  306. /// </summary>
  307. /// <param name="value">This string.</param>
  308. /// <param name="startWith">The start with string.</param>
  309. /// <returns></returns>
  310. public static String EnsureStartsWith(this String value, String startWith)
  311. {
  312. return value != null && value.StartsWith(startWith) ? value : startWith + (value ?? String.Empty);
  313. }
  314. /// <summary>
  315. /// Ensures that the supplied string ends with the specified characters. The characters are appended if not already existing.
  316. /// </summary>
  317. /// <param name="value">The value.</param>
  318. /// <param name="endWith">The end of the string..</param>
  319. /// <returns></returns>
  320. public static String EnsureEndsWith(this String value, String endWith)
  321. {
  322. return value != null && value.EndsWith(endWith) ? value : (value ?? String.Empty) + endWith;
  323. }
  324. #endregion
  325. #region | BINARY
  326. /// <summary>
  327. /// Write the binary field to a target file.
  328. /// </summary>
  329. public static void ToFile(this Binary binary, String targetFile)
  330. {
  331. if ( binary != null )
  332. File.WriteAllBytes(targetFile, binary.ToArray());
  333. }
  334. /// <summary>
  335. /// Write the binary field to a text string.
  336. /// </summary>
  337. public static String ToText(this Binary binary)
  338. {
  339. using ( var ms = new MemoryStream(binary.ToArray()) )
  340. using ( var sr = new StreamReader(ms) )
  341. return sr.ReadToEnd();
  342. }
  343. /// <summary>
  344. /// Write the binary field to an XDocument.
  345. /// </summary>
  346. public static XDocument ToXDocument(this Binary binary)
  347. {
  348. using ( var ms = new MemoryStream(binary.ToArray()) )
  349. using ( var sr = new XmlTextReader(ms) )
  350. return XDocument.Load(sr, LoadOptions.None);
  351. }
  352. #endregion
  353. #region | SERIALIZATION
  354. /// <summary>
  355. /// Serialize the entity as XML to the provided file.
  356. /// </summary>
  357. /// <typeparam name="T">The object type.</typeparam>
  358. public static void SerializeToXml<T>(T entity, String fileName)
  359. {
  360. using (var fileStream = new FileStream(fileName, FileMode.Create))
  361. {
  362. var ser = new XmlSerializer(typeof(T));
  363. ser.Serialize(fileStream, entity);
  364. }
  365. }
  366. /// <summary>
  367. /// Deserialize the entity from XML file.
  368. /// </summary>
  369. /// <typeparam name="T">The object type.</typeparam>
  370. public static T DeserializeFromXml<T>(String xml)
  371. {
  372. T result;
  373. var ser = new XmlSerializer(typeof(T));
  374. using (var tr = new StringReader(xml))
  375. {
  376. result = (T)ser.Deserialize(tr);
  377. }
  378. return result;
  379. }
  380. /// <summary>
  381. /// Serlizes the object to XML, using an empty namespace.
  382. /// </summary>
  383. /// <typeparam name="T">The object type.</typeparam>
  384. public static XDocument Serialize<T>(this T entity) { return Serialize(entity, ""); }
  385. /// <summary>
  386. /// Serlizes the object to XML, using the provided namespace.
  387. /// </summary>
  388. public static XDocument Serialize<T>(this T entity, String nameSpace)
  389. {
  390. var result = new XDocument();
  391. using (var resultWriter = result.CreateWriter())
  392. {
  393. var xmls = new XmlSerializer(typeof(T), nameSpace);
  394. xmls.Serialize(resultWriter, entity);
  395. }
  396. return result;
  397. }
  398. #endregion
  399. #region | XSLT
  400. /// <summary>
  401. /// Transform the XML represented in the XmlReader.
  402. /// </summary>
  403. /// <returns>An Xml reader.</returns>
  404. public static XmlReader Transform(this XslCompiledTransform xslt, XmlReader xml)
  405. {
  406. var result = new XDocument();
  407. using (var resultWriter = result.CreateWriter())
  408. xslt.Transform(xml, resultWriter);
  409. return result.CreateReader();
  410. }
  411. /// <summary>
  412. /// Renders the serialized XML of the entity to an XmlDocument.
  413. /// </summary>
  414. /// <typeparam name="T">The entity type.</typeparam>
  415. public static XmlDocument Render<T>(this XslCompiledTransform xslt, T entity)
  416. {
  417. var xmlDoc = new XmlDocument();
  418. xmlDoc.Load(Transform(xslt, Serialize(entity).CreateReader()));
  419. return xmlDoc;
  420. }
  421. #endregion
  422. }
  423. #region | PATH
  424. //b|
  425. //b| Scrap: Remove as time permits.
  426. //b|
  427. public class Path
  428. {
  429. private String _path = String.Empty;
  430. public Path(String path) { _path = path.TrimEnd('\\'); }
  431. public static implicit operator Path(String value) { return new Path(value); }
  432. public static implicit operator String(Path path) { return path.ToString(); }
  433. public override String ToString() { return _path; }
  434. public static Path GetFullPath(String path) { return System.IO.Path.GetFullPath(path); }
  435. public static Path GetFileName(String path) { return System.IO.Path.GetFileName(path); }
  436. public static Path Combine(String path, String path2) { return System.IO.Path.Combine(path, path2); }
  437. public static Boolean FileExists(Path path) { return System.IO.File.Exists(path); }
  438. public static Boolean FolderExists(Path path) { return System.IO.Directory.Exists(path); }
  439. }
  440. public static class PathExtensions
  441. {
  442. public static Path Combine(this Path path, String path2) { return System.IO.Path.Combine(path, path2); }
  443. public static Path GetFolder(this Path path) { return System.IO.Path.GetDirectoryName(path); }
  444. public static Boolean IsRootPath(this Path path)
  445. {
  446. try
  447. {
  448. GetFolder(GetFolder(path));
  449. return false;
  450. }
  451. catch
  452. {
  453. return true;
  454. }
  455. }
  456. public static Path GetParentFolder(this Path path) { return GetFolder(GetFolder(path)); }
  457. public static Path GetFullPath(this Path path) { return System.IO.Path.GetFullPath(path); }
  458. public static Path GetFileName(this Path path) { return System.IO.Path.GetFileName(path); }
  459. public static Path GetExtension(this Path path) { return System.IO.Path.GetExtension(path); }
  460. public static String EnQuote(this Path path) { return String.Format(@"""{0}""", path); }
  461. public static void CopyPath(this Path source, Path target)
  462. {
  463. if (String.IsNullOrEmpty(source))
  464. throw new ArgumentNullException("source", "The source path cannot be null.");
  465. if (String.IsNullOrEmpty(target))
  466. throw new ArgumentNullException("target", "The target path cannot be null.");
  467. ConsoleProcess.CopyFolder(source, target);
  468. }
  469. }
  470. #endregion
  471. }