PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/DotNetSlave.BusinessLogic/Compilation/LinqLengthExpressionBuilder.cs

#
C# | 161 lines | 62 code | 17 blank | 82 comment | 8 complexity | 9f0545988c8c70f17947a00f8855e82c MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <summary>
  3. // Linq Length Expression Builder
  4. // </summary>
  5. // --------------------------------------------------------------------------------------------------------------------
  6. namespace BlogEngine.Core.Compilation
  7. {
  8. using System;
  9. using System.CodeDom;
  10. using System.Data.Linq.Mapping;
  11. using System.Linq;
  12. using System.Web.Compilation;
  13. using System.Web.UI;
  14. /// <summary>
  15. /// Linq Length Expression Builder
  16. /// </summary>
  17. /// <remarks>
  18. /// The example usage below uses an Employee table with a Name column. Employee may need to be namespace referenced
  19. /// like improvGroup.Manager.Data.Employee if the namespace of the page is different than the data entity namespace.
  20. /// </remarks>
  21. /// <example>
  22. /// &lt;asp:TextBox ID="TextBoxName" runat="server" MaxLength='&lt;%$LinqLength:Employee.Name%&gt;' /&gt;
  23. /// </example>
  24. [ExpressionPrefix("LinqLength")]
  25. public class LinqLengthExpressionBuilder : ExpressionBuilder
  26. {
  27. #region Public Methods
  28. /// <summary>
  29. /// Gets the code expression.
  30. /// </summary>
  31. /// <param name="entry">
  32. /// The entry.
  33. /// </param>
  34. /// <param name="parsedData">
  35. /// The parsed data.
  36. /// </param>
  37. /// <param name="context">
  38. /// The context.
  39. /// </param>
  40. /// <returns>
  41. /// A CodeExpression.
  42. /// </returns>
  43. public override CodeExpression GetCodeExpression(
  44. BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
  45. {
  46. var typeName = BeforeLast(entry.Expression, ".");
  47. var propertyName = AfterLast(entry.Expression, ".");
  48. return new CodePrimitiveExpression(PropertyLength(typeName, propertyName));
  49. }
  50. #endregion
  51. #region Methods
  52. /// <summary>
  53. /// Gets the end of the string after the last instance of the last.
  54. /// </summary>
  55. /// <param name="value">
  56. /// The string value.
  57. /// </param>
  58. /// <param name="last">
  59. /// The value to search for.
  60. /// </param>
  61. /// <returns>
  62. /// The string after the last instance of last.
  63. /// </returns>
  64. private static string AfterLast(string value, string last)
  65. {
  66. if (value == null)
  67. {
  68. throw new ArgumentNullException("value");
  69. }
  70. return value.Substring(value.LastIndexOf(last) + last.Length);
  71. }
  72. /// <summary>
  73. /// Get the string up to the last instance of last.
  74. /// </summary>
  75. /// <param name="value">
  76. /// The string value.
  77. /// </param>
  78. /// <param name="last">
  79. /// The instance to search for the last of.
  80. /// </param>
  81. /// <returns>
  82. /// The string up to the last instance of last.
  83. /// </returns>
  84. private static string BeforeLast(string value, string last)
  85. {
  86. if (value == null)
  87. {
  88. throw new ArgumentNullException("value");
  89. }
  90. if (last == null)
  91. {
  92. throw new ArgumentNullException("last");
  93. }
  94. return value.Substring(0, value.LastIndexOf(last));
  95. }
  96. /// <summary>
  97. /// Gets the string value between the start and the end.
  98. /// </summary>
  99. /// <param name="value">
  100. /// The value to search.
  101. /// </param>
  102. /// <param name="startText">
  103. /// The start text to skip.
  104. /// </param>
  105. /// <param name="endText">
  106. /// The end text to skip.
  107. /// </param>
  108. /// <returns>
  109. /// The middle of the string between start and end.
  110. /// </returns>
  111. private static string BetweenFirst(string value, string startText, string endText)
  112. {
  113. if (value == null)
  114. {
  115. throw new ArgumentNullException("value");
  116. }
  117. var start = value.IndexOf(startText, StringComparison.OrdinalIgnoreCase) + startText.Length;
  118. var end = value.IndexOf(endText, start, StringComparison.OrdinalIgnoreCase);
  119. return value.Substring(start, end - start);
  120. }
  121. /// <summary>
  122. /// Gets the length of the property.
  123. /// </summary>
  124. /// <param name="typeName">
  125. /// Name of the type.
  126. /// </param>
  127. /// <param name="propertyName">
  128. /// Name of the property.
  129. /// </param>
  130. /// <returns>
  131. /// The length of the property.
  132. /// </returns>
  133. private static int PropertyLength(string typeName, string propertyName)
  134. {
  135. var attribute =
  136. (ColumnAttribute)
  137. BuildManager.GetType(typeName, true).GetProperty(propertyName).GetCustomAttributes(
  138. typeof(ColumnAttribute), false).Single();
  139. // <-- look, I just had to use a tiny bit of LINQ in this code!
  140. return int.Parse(BetweenFirst(attribute.DbType, "char(", ")"));
  141. }
  142. #endregion
  143. }
  144. }