Clover.NET coverage report - Coverage

Coverage timestamp: Friday, May 20, 2005 9:17:00 PM

File Stats: LOC: 705   Methods: 18
NCLOC: 504 Classes: 1

Warning

The source file used to generate this report was changed after Clover generated coverage information. The coverage reported may not match the source lines. You should regenerate the coverage information and the report to ensure the files are in sync.

 
Source File Conditionals Statements Methods TOTAL
Utilities\Objects\ObjectProbe.cs 28.4 % 38.2 % 50.0 % 36.2 %
coverage coverage
1  
2   #region Apache Notice
3   /*****************************************************************************
4   * $Header: $
5   * $Revision: $
6   * $Date: $
7   *
8   * iBATIS.NET Data Mapper
9   * Copyright (C) 2004 - Gilles Bayon
10   *
11   *
12   * Licensed under the Apache License, Version 2.0 (the "License");
13   * you may not use this file except in compliance with the License.
14   * You may obtain a copy of the License at
15   *
16   * http://www.apache.org/licenses/LICENSE-2.0
17   *
18   * Unless required by applicable law or agreed to in writing, software
19   * distributed under the License is distributed on an "AS IS" BASIS,
20   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   * See the License for the specific language governing permissions and
22   * limitations under the License.
23   *
24   ********************************************************************************/
25   #endregion
26  
27   using System;
28   using System.Collections;
29   using System.Reflection;
30  
31   using IBatisNet.Common.Exceptions;
32  
33   namespace IBatisNet.Common.Utilities.Objects
34   {
35   /// <summary>
36   /// Description résumée de ObjectProbe.
37   /// </summary>
38   public class ObjectProbe
39   {
40   private static ArrayList _simpleTypeMap = new ArrayList();
41  
42 1 static ObjectProbe()
43   {
44 1 _simpleTypeMap.Add(typeof(string));
45 1 _simpleTypeMap.Add(typeof(Byte));
46 1 _simpleTypeMap.Add(typeof(Int16));
47 1 _simpleTypeMap.Add(typeof(char));
48 1 _simpleTypeMap.Add(typeof(Int32));
49 1 _simpleTypeMap.Add(typeof(Int64));
50 1 _simpleTypeMap.Add(typeof(Single));
51 1 _simpleTypeMap.Add(typeof(Double));
52 1 _simpleTypeMap.Add(typeof(Boolean));
53 1 _simpleTypeMap.Add(typeof(DateTime));
54 1 _simpleTypeMap.Add(typeof(Decimal));
55  
56   // _simpleTypeMap.Add(typeof(Hashtable));
57   // _simpleTypeMap.Add(typeof(SortedList));
58   // _simpleTypeMap.Add(typeof(ArrayList));
59   // _simpleTypeMap.Add(typeof(Array));
60  
61   // simpleTypeMap.Add(LinkedList.class);
62   // simpleTypeMap.Add(HashSet.class);
63   // simpleTypeMap.Add(TreeSet.class);
64   // simpleTypeMap.Add(Vector.class);
65   // simpleTypeMap.Add(Hashtable.class);
66 1 _simpleTypeMap.Add(typeof(SByte));
67 1 _simpleTypeMap.Add(typeof(UInt16));
68 1 _simpleTypeMap.Add(typeof(UInt32));
69 1 _simpleTypeMap.Add(typeof(UInt64));
70 1 _simpleTypeMap.Add(typeof(IEnumerator));
71   }
72  
73  
74   /// <summary>
75   /// Returns an array of the readable properties names exposed by an object
76   /// </summary>
77   /// <param name="obj">The object</param>
78   /// <returns>The properties name</returns>
79 0 public static string[] GetReadablePropertyNames(object obj)
80   {
81   return ReflectionInfo.GetInstance(obj.GetType()).GetReadablePropertyNames();
82   }
83  
84  
85   /// <summary>
86   /// Returns an array of the writeable properties name exposed by a object
87   /// </summary>
88   /// <param name="obj">The object</param>
89   /// <returns>The properties name</returns>
90 0 public static string[] GetWriteablePropertyNames(object obj)
91   {
92   return ReflectionInfo.GetInstance(obj.GetType()).GetWriteablePropertyNames();
93   }
94  
95   /// <summary>
96   /// Returns the type that the set expects to receive as a parameter when
97   /// setting a property value.
98   /// </summary>
99   /// <param name="obj">The object to check</param>
100   /// <param name="propertyName">The name of the property</param>
101   /// <returns>The type of the property</returns>
102 0 private static Type GetPropertyTypeForSetter(object obj, string propertyName)
103   {
104   Type type = obj.GetType();
105  
106   if (obj is IDictionary)
107   {
108   IDictionary map = (IDictionary) obj;
109   object value = map[propertyName];
110   if (value == null)
111   {
112   type = typeof(object);
113   }
114   else
115   {
116   type = value.GetType();
117   }
118   }
119   else
120   {
121   if (propertyName.IndexOf('.') > -1)
122   {
123   StringTokenizer parser = new StringTokenizer(propertyName, ".");
124   IEnumerator enumerator = parser.GetEnumerator();
125  
126   while (enumerator.MoveNext())
127   {
128   propertyName = (string)enumerator.Current;
129   type = ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
130   }
131   }
132   else
133   {
134   type = ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
135   }
136   }
137  
138   return type;
139   }
140  
141  
142   /// <summary>
143   /// Returns the type that the set expects to receive as a parameter when
144   /// setting a property value.
145   /// </summary>
146   /// <param name="type">The type to check</param>
147   /// <param name="propertyName">The name of the property</param>
148   /// <returns>The type of the property</returns>
149 0 private static Type GetPropertyTypeForSetter(Type type, string propertyName)
150   {
151   if (propertyName.IndexOf('.') > -1)
152   {
153   StringTokenizer parser = new StringTokenizer(propertyName, ".");
154   IEnumerator enumerator = parser.GetEnumerator();
155  
156   while (enumerator.MoveNext())
157   {
158   propertyName = (string)enumerator.Current;
159   type = ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
160   }
161   }
162   else
163   {
164   type = ReflectionInfo.GetInstance(type).GetSetterType(propertyName);
165   }
166  
167   return type;
168   }
169  
170  
171   /// <summary>
172   /// Returns the type that the get expects to receive as a parameter when
173   /// setting a property value.
174   /// </summary>
175   /// <param name="obj">The object to check</param>
176   /// <param name="propertyName">The name of the property</param>
177   /// <returns>The type of the property</returns>
178 0 public static Type GetPropertyTypeForGetter(object obj, string propertyName)
179   {
180   Type type = obj.GetType();
181  
182   if (obj is IDictionary)
183   {
184   IDictionary map = (IDictionary) obj;
185   object value = map[propertyName];
186   if (value == null)
187   {
188   type = typeof(object);
189   }
190   else
191   {
192   type = value.GetType();
193   }
194   }
195   else
196   {
197   if (propertyName.IndexOf('.') > -1)
198   {
199   StringTokenizer parser = new StringTokenizer(propertyName, ".");
200   IEnumerator enumerator = parser.GetEnumerator();
201  
202   while (enumerator.MoveNext())
203   {
204   propertyName = (string)enumerator.Current;
205   type = ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
206   }
207   }
208   else
209   {
210   type = ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
211   }
212   }
213  
214   return type;
215   }
216  
217  
218   /// <summary>
219   /// Returns the type that the get expects to receive as a parameter when
220   /// setting a property value.
221   /// </summary>
222   /// <param name="type">The type to check</param>
223   /// <param name="propertyName">The name of the property</param>
224   /// <returns>The type of the property</returns>
225 28560 public static Type GetPropertyTypeForGetter(Type type, string propertyName)
226   {
227 28560 if (propertyName.IndexOf('.') > -1)
228   {
229 510 StringTokenizer parser = new StringTokenizer(propertyName, ".");
230 510 IEnumerator enumerator = parser.GetEnumerator();
231  
232 1530 while (enumerator.MoveNext())
233   {
234 1020 propertyName = (string)enumerator.Current;
235 1020 type = ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
236   }
237   }
238   else
239   {
240 28050 type = ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
241   }
242  
243 28560 return type;
244   }
245  
246  
247  
248 21 private static object GetArrayProperty(object obj, string indexedName)
249   {
250  
251 21 object value = null;
252  
253 21 try
254   {
255 21 int startIndex = indexedName.IndexOf("[");
256 21 int length = indexedName.IndexOf("]");
257 21 string name = indexedName.Substring(0, startIndex);
258 21 string index = indexedName.Substring( startIndex+1, length-(startIndex+1));
259 21 int i = System.Convert.ToInt32(index);
260  
261 21 if (name.Length > 0)
262   {
263 6 value = GetProperty(obj, name);
264   }
265   else
266   {
267 15 value = obj;
268   }
269  
270 21 if (value is IList)
271   {
272 21 value = ((IList) value)[i];
273   }
274   else
275   {
276 0 throw new ProbeException("The '" + name + "' property of the " + obj.GetType().Name + " class is not a List or Array.");
277   }
278   }
279   catch (ProbeException pe)
280   {
281 0 throw pe;
282   }
283   catch(Exception e)
284   {
285 0 throw new ProbeException("Error getting ordinal value from .net object. Cause" + e.Message, e);
286   }
287  
288 21 return value;
289   }
290  
291  
292   /// <summary>
293   ///
294   /// </summary>
295   /// <param name="obj"></param>
296   /// <param name="propertyName"></param>
297   /// <returns></returns>
298 593 protected static object GetProperty(object obj, string propertyName)
299   {
300 593 ReflectionInfo reflectionCache = ReflectionInfo.GetInstance(obj.GetType());
301  
302 593 try
303   {
304 593 object value = null;
305  
306 593 if (propertyName.IndexOf("[") > -1)
307   {
308 21 value = GetArrayProperty(obj, propertyName);
309   }
310   else
311   {
312 572 if (obj is IDictionary)
313   {
314 58 value = ((IDictionary) obj)[propertyName];
315   }
316   else
317   {
318 514 PropertyInfo propertyInfo = reflectionCache.GetGetter(propertyName);
319 513 if (propertyInfo == null)
320   {
321 0 throw new ProbeException("No Get method for property " + propertyName + " on instance of " + obj.GetType().Name);
322   }
323 513 try
324   {
325 513 value = propertyInfo.GetValue(obj, null);
326   }
327   catch (ArgumentException ae)
328   {
329 0 throw new ProbeException(ae);
330   }
331   catch (TargetException t)
332   {
333 0 throw new ProbeException(t);
334   }
335   catch (TargetParameterCountException tp)
336   {
337 0 throw new ProbeException(tp);
338   }
339   catch (MethodAccessException ma)
340   {
341 0 throw new ProbeException(ma);
342   }
343   }
344   }
345 592 return value;
346   }
347   catch (ProbeException pe)
348   {
349 1 throw pe;
350   }
351   catch(Exception e)
352   {
353 0 throw new ProbeException("Could not Set property '" + propertyName + "' for " + obj.GetType().Name + ". Cause: " + e.Message, e);
354   }
355   }
356  
357  
358 0 private static void SetArrayProperty(object obj, string indexedName, object value)
359   {
360   try
361   {
362   int startIndex = indexedName.IndexOf("[");
363   int length = indexedName.IndexOf("]");
364   string name = indexedName.Substring(0, startIndex);
365   string index = indexedName.Substring( startIndex+1, length-(startIndex+1));
366   int i = System.Convert.ToInt32(index);
367  
368   object list = null;
369   if (name.Length > 0)
370   {
371   list = GetProperty(obj, name);
372   }
373   else
374   {
375   list = obj;
376   }
377  
378   if (list is IList)
379   {
380   ((IList) list)[i] = value;
381   }
382   else
383   {
384   throw new ProbeException("The '" + name + "' property of the " + obj.GetType().Name + " class is not a List or Array.");
385   }
386   }
387   catch (ProbeException pe)
388   {
389   throw pe;
390   }
391   catch (Exception e)
392   {
393   throw new ProbeException("Error getting ordinal value from .net object. Cause" + e.Message, e);
394   }
395   }
396  
397  
398   /// <summary>
399   ///
400   /// </summary>
401   /// <param name="obj"></param>
402   /// <param name="propertyName"></param>
403   /// <param name="propertyValue"></param>
404 4015 protected static void SetProperty(object obj, string propertyName, object propertyValue)
405   {
406 4015 ReflectionInfo reflectionCache = ReflectionInfo.GetInstance(obj.GetType());
407  
408 4015 try
409   {
410 4015 if (propertyName.IndexOf("[") > -1)
411   {
412 0 SetArrayProperty(obj, propertyName, propertyValue);
413   }
414   else
415   {
416 4015 if (obj is IDictionary)
417   {
418 3 ((IDictionary) obj)[propertyName] = propertyValue;
419   }
420   else
421   {
422 4012 PropertyInfo propertyInfo = reflectionCache.GetSetter(propertyName);
423  
424 4012 if (propertyInfo == null)
425   {
426 0 throw new ProbeException("No Set method for property " + propertyName + " on instance of " + obj.GetType().Name);
427   }
428 4012 try
429   {
430 4012 propertyInfo.SetValue(obj, propertyValue, null);
431   }
432   catch (ArgumentException ae)
433   {
434 0 throw new ProbeException(ae);
435   }
436   catch (TargetException t)
437   {
438 0 throw new ProbeException(t);
439   }
440   catch (TargetParameterCountException tp)
441   {
442 0 throw new ProbeException(tp);
443   }
444   catch (MethodAccessException ma)
445   {
446 0 throw new ProbeException(ma);
447   }
448   }
449   }
450   }
451   catch (ProbeException pe)
452   {
453 0 throw pe;
454   }
455   catch (Exception e)
456   {
457 0 throw new ProbeException("Could not Get property '" + propertyName + "' for " + obj.GetType().Name + ". Cause: " + e.Message, e);
458   }
459   }
460  
461  
462   /// <summary>
463   /// Return the specified property on an object.
464   /// </summary>
465   /// <param name="obj">The Object on which to invoke the specified property.</param>
466   /// <param name="propertyName">The name of the property.</param>
467   /// <returns>An Object representing the return value of the invoked property.</returns>
468 571 public static object GetPropertyValue(object obj, string propertyName)
469   {
470 571 if (propertyName.IndexOf('.') > -1)
471   {
472 15 StringTokenizer parser = new StringTokenizer(propertyName, ".");
473 15 IEnumerator enumerator = parser.GetEnumerator();
474 15 object value = obj;
475 15 string token = null;
476  
477 46 while (enumerator.MoveNext())
478   {
479 31 token = (string)enumerator.Current;
480 31 value = GetProperty(value, token);
481  
482 31 if (value == null)
483   {
484 0 break;
485   }
486   }
487 15 return value;
488   }
489   else
490   {
491 556 return GetProperty(obj, propertyName);
492   }
493   }
494  
495  
496   /// <summary>
497   /// Set the specified property on an object
498   /// </summary>
499   /// <param name="obj">The Object on which to invoke the specified property.</param>
500   /// <param name="propertyName">The name of the property to set.</param>
501   /// <param name="propertyValue">The new value to set.</param>
502 4015 public static void SetPropertyValue(object obj, string propertyName, object propertyValue)
503   {
504 4015 if (propertyName.IndexOf('.') > -1)
505   {
506 0 StringTokenizer parser = new StringTokenizer(propertyName, ".");
507 0 IEnumerator enumerator = parser.GetEnumerator();
508 0 enumerator.MoveNext();
509  
510 0 string currentPropertyName = (string)enumerator.Current;
511 0 object child = obj;
512  
513 0 while (enumerator.MoveNext())
514   {
515   Type type = GetPropertyTypeForSetter(child, currentPropertyName);
516   object parent = child;
517   child = GetProperty(parent, currentPropertyName);
518   if (child == null)
519   {
520   try
521   {
522   child = Activator.CreateInstance(type);
523   SetPropertyValue(parent, currentPropertyName, child);
524   }
525   catch (Exception e)
526   {
527   throw new ProbeException("Cannot set value of property '" + propertyName + "' because '" + currentPropertyName + "' is null and cannot be instantiated on instance of " + type.Name + ". Cause:" + e.Message, e);
528   }
529   }
530   currentPropertyName = (string)enumerator.Current;
531   }
532 0 SetProperty(child, currentPropertyName, propertyValue);
533   }
534   else
535   {
536 4015 SetProperty(obj, propertyName, propertyValue);
537   }
538   }
539  
540  
541   /// <summary>
542   /// Checks to see if a Object has a writable property/field be a given name
543   /// </summary>
544   /// <param name="obj"> The object to check</param>
545   /// <param name="propertyName">The property to check for</param>
546   /// <returns>True if the property exists and is writable</returns>
547 0 public static bool HasWritableProperty(object obj, string propertyName)
548   {
549   bool hasProperty = false;
550   if (obj is IDictionary)
551   {
552   hasProperty = ((IDictionary) obj).Contains(propertyName);
553   }
554   else
555   {
556   if (propertyName.IndexOf('.') > -1)
557   {
558   StringTokenizer parser = new StringTokenizer(propertyName, ".");
559   IEnumerator enumerator = parser.GetEnumerator();
560   Type type = obj.GetType();
561  
562   while (enumerator.MoveNext())
563   {
564   propertyName = (string)enumerator.Current;
565   type = ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
566   hasProperty = ReflectionInfo.GetInstance(type).HasWritableProperty(propertyName);
567   }
568   }
569   else
570   {
571   hasProperty = ReflectionInfo.GetInstance(obj.GetType()).HasWritableProperty(propertyName);
572   }
573   }
574   return hasProperty;
575   }
576  
577  
578   /// <summary>
579   /// Checks to see if the Object have a property/field be a given name.
580   /// </summary>
581   /// <param name="obj">The Object on which to invoke the specified property.</param>
582   /// <param name="propertyName">The name of the property to check for.</param>
583   /// <returns>
584   /// True or false if the property exists and is readable.
585   /// </returns>
586 2 public static bool HasReadableProperty(object obj, string propertyName)
587   {
588 2 bool hasProperty = false;
589  
590 2 if (obj is IDictionary)
591   {
592 0 hasProperty = ((IDictionary) obj).Contains(propertyName);
593   }
594   else
595   {
596 2 if (propertyName.IndexOf('.') > -1)
597   {
598 0 StringTokenizer parser = new StringTokenizer(propertyName, ".");
599 0 IEnumerator enumerator = parser.GetEnumerator();
600 0 Type type = obj.GetType();
601  
602 0 while (enumerator.MoveNext())
603   {
604   propertyName = (string)enumerator.Current;
605   type = ReflectionInfo.GetInstance(type).GetGetterType(propertyName);
606   hasProperty = ReflectionInfo.GetInstance(type).HasReadableProperty(propertyName);
607   }
608   }
609   else
610   {
611 2 hasProperty = ReflectionInfo.GetInstance(obj.GetType()).HasReadableProperty(propertyName);
612   }
613   }
614  
615 2 return hasProperty;
616   }
617  
618  
619   /// <summary>
620   ///
621   /// </summary>
622   /// <param name="type"></param>
623   /// <returns></returns>
624 0 public static bool IsSimpleType(Type type)
625   {
626   if (_simpleTypeMap.Contains(type))
627   {
628   return true;
629   }
630   else if (type.IsSubclassOf(typeof(ICollection)))
631   {
632   return true;
633   }
634   else if (type.IsSubclassOf(typeof(IDictionary)))
635   {
636   return true;
637   }
638   else if (type.IsSubclassOf(typeof(IList)))
639   {
640   return true;
641   }
642   else if (type.IsSubclassOf(typeof(IEnumerable)))
643   {
644   return true;
645   }
646   else
647   {
648   return false;
649   }
650   }
651  
652  
653   /// <summary>
654   /// Calculates a hash code for all readable properties of a object.
655   /// </summary>
656   /// <param name="obj">The object to calculate the hash code for.</param>
657   /// <returns>The hash code.</returns>
658 0 public static int ObjectHashCode(object obj)
659   {
660   return ObjectHashCode(obj, GetReadablePropertyNames(obj));
661   }
662  
663  
664   /// <summary>
665   /// Calculates a hash code for a subset of the readable properties of a object.
666   /// </summary>
667   /// <param name="obj">The object to calculate the hash code for.</param>
668   /// <param name="properties">A list of the properties to hash.</param>
669   /// <returns>The hash code.</returns>
670 1 public static int ObjectHashCode(object obj, string[] properties )
671   {
672 1 ArrayList alreadyDigested = new ArrayList();
673  
674 1 int hashcode = obj.GetType().FullName.GetHashCode();
675 1 for (int i = 0; i < properties.Length; i++)
676   {
677 0 object value = GetProperty(obj, properties[i]);
678 0 if (value != null)
679   {
680   if (IsSimpleType(value.GetType()))
681   {
682   hashcode += value.GetHashCode();
683   }
684   else
685   {
686   // It's a Object
687   // Check to avoid endless loop (circular dependency)
688   if (value != obj)
689   {
690   if (!alreadyDigested.Contains(value))
691   {
692   alreadyDigested.Add(value);
693   hashcode += ObjectHashCode(value);
694   }
695   }
696   }
697   hashcode *= 29;
698   }
699   }
700 1 return hashcode;
701   }
702  
703   }
704   }
705