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