2008-03-13 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / BaseCompareValidator.cs
1 //
2 // System.Web.UI.WebControls.BaseCompareValidator
3 //
4 // Authors:
5 //      Chris Toshok (toshok@novell.com)
6 //
7 // (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.Text;
30 using System.Threading;
31 using System.Globalization;
32 using System.ComponentModel;
33 using System.Security.Permissions;
34
35 namespace System.Web.UI.WebControls {
36
37         // CAS
38         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
40         public abstract class BaseCompareValidator : BaseValidator {
41
42 #if NET_2_0
43                 protected
44 #else
45                 public
46 #endif
47                 BaseCompareValidator ()
48                 {
49                 }
50
51                 protected override void AddAttributesToRender (HtmlTextWriter w)
52                 {
53                         if (RenderUplevel) {
54 #if NET_2_0
55                                 if (Page!=null){
56                                         RegisterExpandoAttribute (ClientID, "type", Type.ToString ());
57
58                                         switch (Type) {
59                                         case ValidationDataType.Date:
60                                                 DateTimeFormatInfo dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;
61                                                 string pattern = dateTimeFormat.ShortDatePattern;
62                                                 string dateorder = (pattern.StartsWith ("y", true, CultureInfo.InvariantCulture) ? "ymd" : (pattern.StartsWith ("m", true, CultureInfo.InvariantCulture) ? "mdy" : "dmy"));
63                                                 RegisterExpandoAttribute (ClientID, "dateorder", dateorder);
64                                                 RegisterExpandoAttribute (ClientID, "cutoffyear", dateTimeFormat.Calendar.TwoDigitYearMax.ToString ());
65                                                 break;
66                                         case ValidationDataType.Currency:
67                                                 NumberFormatInfo numberFormat = CultureInfo.CurrentCulture.NumberFormat;
68                                                 RegisterExpandoAttribute (ClientID, "decimalchar", numberFormat.CurrencyDecimalSeparator, true);
69                                                 RegisterExpandoAttribute (ClientID, "groupchar", numberFormat.CurrencyGroupSeparator, true);
70                                                 RegisterExpandoAttribute (ClientID, "digits", numberFormat.CurrencyDecimalDigits.ToString());
71                                                 RegisterExpandoAttribute (ClientID, "groupsize", numberFormat.CurrencyGroupSizes [0].ToString ());
72                                                 break;
73                                         }
74                                 }
75 #else
76                                 w.AddAttribute ("datatype", Type.ToString());
77 #endif
78                         }
79
80                         base.AddAttributesToRender (w);
81                 }
82
83                 public static bool CanConvert (string text,
84                                                ValidationDataType type)
85                 {
86                         object value;
87
88                         return Convert (text, type, out value);
89                 }
90
91                 protected static bool Convert (string text,
92                                                ValidationDataType type,
93                                                out object value)
94                 {
95                         return BaseCompareValidator.Convert(text, type, false, out value);
96                 }
97
98                 protected static bool Compare (string left,
99                                                string right,
100                                                ValidationCompareOperator op,
101                                                ValidationDataType type)
102                 {
103                         return BaseCompareValidator.Compare(left, false, right, false, op, type);       
104                 }
105
106                 protected override bool DetermineRenderUplevel ()
107                 {
108                         /* presumably the CompareValidator client side
109                          * code makes use of newer dom/js stuff than
110                          * the rest of the validators.  but ours
111                          * doesn't for the moment, so let's just use
112                          * our present implementation
113                          */
114                         return base.DetermineRenderUplevel();
115                 }
116
117                 protected static string GetDateElementOrder ()
118                 {
119                         // I hope there's a better way to implement this...
120                         string pattern = Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern;
121                         StringBuilder order = new StringBuilder();
122                         bool seen_date = false;
123                         bool seen_year = false;
124                         bool seen_month = false;
125
126                         pattern = pattern.ToLower (CultureInfo.InvariantCulture);
127
128                         for (int i = 0; i < pattern.Length; i ++) {
129                                 char c = pattern[ i ];
130                                 if (c != 'm' && c != 'd' && c != 'y')
131                                         continue;
132
133                                 if (c == 'm') {
134                                         if (!seen_month) order.Append ("m");
135                                         seen_month = true;
136                                 }
137                                 else if (c == 'y') {
138                                         if (!seen_year) order.Append ("y");
139                                         seen_year = true;
140                                 }
141                                 else /* (c == 'd') */ {
142                                         if (!seen_date) order.Append ("d");
143                                         seen_date = true;
144                                 }
145                         }
146
147                         return order.ToString ();
148                 }
149
150                 protected static int GetFullYear (int two_digit_year)
151                 {
152 #if NET_2_0
153                         /* This is an implementation that matches the
154                          * docs on msdn, but MS doesn't seem to go by
155                          * their docs (at least in 1.0). */
156                         int cutoff = CutoffYear;
157                         int twodigitcutoff = cutoff % 100;
158
159                         if (two_digit_year <= twodigitcutoff) {
160                                 return cutoff - twodigitcutoff + two_digit_year;
161                         }
162                         else {
163                                 return cutoff - twodigitcutoff - 100 + two_digit_year;
164                         }
165 #else
166                         /* This is the broken implementation in 1.0 */
167                         int cutoff = CutoffYear;
168                         int twodigitcutoff = cutoff % 100;
169
170                         return cutoff - twodigitcutoff + two_digit_year;
171 #endif
172                 }
173
174 #if NET_2_0
175                 [DefaultValue (false)]
176                 [Themeable (false)]
177                 public
178 #else 
179                 internal
180 #endif
181             bool CultureInvariantValues {
182                         get { return ViewState.GetBool ("CultureInvariantValues", false); }
183                         set { ViewState ["CultureInvariantValues"] = value; }
184                 }
185
186
187                 
188                 protected static int CutoffYear {
189                         get {
190                                 return CultureInfo.CurrentCulture.Calendar.TwoDigitYearMax;
191                         }
192                 }
193
194
195                 [DefaultValue(ValidationDataType.String)]
196 #if NET_2_0
197                 [Themeable (false)]
198 #endif
199                 [WebSysDescription("")]
200                 [WebCategory("Behavior")]
201                 public ValidationDataType Type {
202                         get { return ViewState ["Type"] == null ? ValidationDataType.String : (ValidationDataType) ViewState ["Type"]; }
203                         set { ViewState ["Type"] = value; }
204                 }
205
206 #if NET_2_0
207                 
208                 public
209 #else 
210         internal
211 #endif 
212         static bool CanConvert (string text, 
213                                                ValidationDataType type, 
214                                                bool cultureInvariant)
215                 {
216                         object value;
217                         return Convert(text, type, cultureInvariant, out value);
218                 }
219
220 #if NET_2_0
221                 protected
222 #else 
223         internal
224 #endif 
225         static bool Compare (string left, 
226                                                bool cultureInvariantLeftText, 
227                                                string right, 
228                                                bool cultureInvariantRightText, 
229                                                ValidationCompareOperator op, 
230                                                ValidationDataType type)
231                 {
232             object lo, ro;
233
234             if (!Convert(left, type, cultureInvariantLeftText, out lo))
235                 return false;
236
237             /* DataTypeCheck is a unary operator that only
238              * depends on the lhs */
239             if (op == ValidationCompareOperator.DataTypeCheck)
240                 return true;
241
242             /* pretty crackladen, but if we're unable to
243              * convert the rhs to @type, the comparison
244              * succeeds */
245             if (!Convert(right, type, cultureInvariantRightText, out ro))
246                 return true;
247
248             int comp = ((IComparable)lo).CompareTo((IComparable)ro);
249
250             switch (op)
251             {
252                 case ValidationCompareOperator.Equal:
253                     return comp == 0;
254                 case ValidationCompareOperator.NotEqual:
255                     return comp != 0;
256                 case ValidationCompareOperator.LessThan:
257                     return comp < 0;
258                 case ValidationCompareOperator.LessThanEqual:
259                     return comp <= 0;
260                 case ValidationCompareOperator.GreaterThan:
261                     return comp > 0;
262                 case ValidationCompareOperator.GreaterThanEqual:
263                     return comp >= 0;
264                 default:
265                     return false;
266             }
267                 }
268
269 #if NET_2_0
270         protected
271 #else
272         internal
273 #endif
274                 static bool Convert (string text,
275                                                ValidationDataType type,
276                                                bool cultureInvariant,
277                                                out object value)
278                 {
279             try
280             {
281                 switch (type)
282                 {
283                     case ValidationDataType.String:
284                         value = text;
285                         return value != null;
286
287                     case ValidationDataType.Integer:
288                         IFormatProvider intFormatProvider = (cultureInvariant) ? 
289                             NumberFormatInfo.InvariantInfo :
290                             NumberFormatInfo.CurrentInfo;
291                         value = Int32.Parse(text, intFormatProvider);
292                         return true;
293
294                     case ValidationDataType.Double:
295                         IFormatProvider doubleFormatProvider = (cultureInvariant) ?
296                             NumberFormatInfo.InvariantInfo :
297                             NumberFormatInfo.CurrentInfo;
298                         value = Double.Parse(text, doubleFormatProvider);
299                         return true;
300
301                     case ValidationDataType.Date:
302                         
303                         IFormatProvider dateFormatProvider = (cultureInvariant) ? 
304                             DateTimeFormatInfo.InvariantInfo :
305                             DateTimeFormatInfo.CurrentInfo;
306
307                         value = DateTime.Parse(text, dateFormatProvider);
308                         return true;
309
310                     case ValidationDataType.Currency:
311                         IFormatProvider currencyFormatProvider = (cultureInvariant) ?
312                             NumberFormatInfo.InvariantInfo :
313                             NumberFormatInfo.CurrentInfo;
314                         value = Decimal.Parse(text, NumberStyles.Currency, currencyFormatProvider);
315                         return true;
316
317                     default:
318                         value = null;
319                         return false;
320                 }
321             }
322             catch
323             {
324                 value = null;
325                 return false;
326             }
327                 }
328         }
329
330 }
331
332
333
334
335
336
337