-
Notifications
You must be signed in to change notification settings - Fork 476
Expand file tree
/
Copy pathEntity.cs
More file actions
145 lines (125 loc) · 5.12 KB
/
Entity.cs
File metadata and controls
145 lines (125 loc) · 5.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using Castle.Core.Logging;
using TestStack.White.Configuration;
using TestStack.White.UIItems.TableItems;
namespace TestStack.White.ScreenObjects.EntityMapping
{
/// <summary>
/// Represents an entity which can be mapped to the screen objects.
/// </summary>
[Serializable]
public class Entity
{
[ScreenIgnore, XmlIgnore] private NestedEntities nestedEntities;
private readonly ILogger logger = CoreConfigurationLocator.Get().LoggerFactory.Create(typeof(Entity));
internal const BindingFlags BindingFlag = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase;
protected Entity() {}
public Entity(TableRow tableRow, IList<string> header) : this()
{
int index = 0;
foreach (TableCell cell in tableRow.Cells)
AddData(header, index++, GetColumnValue(cell));
}
public virtual EntityField Field(string fieldName)
{
return (from entity in NestedEntities
let entityType = entity.GetType()
let field = entityType.GetField(fieldName, BindingFlag)
where field != null
select new EntityField(entity, field))
.FirstOrDefault();
}
private IEnumerable<Entity> NestedEntities
{
get { return nestedEntities ?? (nestedEntities = new NestedEntities(this)); }
}
public override string ToString()
{
return BuildStringRepresentation(new EntityTranslator(this).ToString);
}
public virtual string Header
{
get { return BuildStringRepresentation(new EntityTranslator(this).ToHeader); }
}
private void AddData(IList<string> header, int index, string value)
{
string fieldName = HeaderFormatter.To_Field_Name(header[index]);
EntityField entityField = Field(fieldName);
if (entityField == null) logger.DebugFormat("Could not find field: {0} in {1}", fieldName, GetType());
else
{
entityField.SetValue(value);
}
}
// ReSharper disable ClassWithVirtualMembersNeverInherited.Local
private class EntityTranslator
{
private readonly Entity entity;
public EntityTranslator(Entity entity)
{
this.entity = entity;
}
public virtual string ToString(FieldInfo fieldInfo)
{
var builder = new StringBuilder();
builder.Append(fieldInfo.Name).Append("=");
if (IsAnEntity(fieldInfo))
{
builder.Append(fieldInfo.GetValue(entity));
}
else
{
builder.Append(fieldInfo.GetValue(entity)).Append(", ");
}
return builder.ToString();
}
public virtual string ToHeader(FieldInfo fieldInfo)
{
return IsAnEntity(fieldInfo) ? ((Entity) fieldInfo.GetValue(entity)).Header : HeaderFormatter.To_Header_Column(fieldInfo.Name) + ", ";
}
private static bool IsAnEntity(FieldInfo fieldInfo)
{
return typeof (Entity).IsAssignableFrom(fieldInfo.FieldType);
}
}
// ReSharper restore ClassWithVirtualMembersNeverInherited.Local
private delegate string Translate(FieldInfo fieldInfo);
private string BuildStringRepresentation(Translate translate)
{
var builder = new StringBuilder();
foreach (var fieldInfo in GetType().GetFields(BindingFlag))
{
if (fieldInfo.GetCustomAttributes(typeof(ScreenIgnoreAttribute), false).Length != 1)
builder.Append(translate(fieldInfo));
}
return builder.ToString();
}
public class HeaderFormatter
{
// This replaces /es with '_or_' and spaces with '_'. a.k.a 'One Two' will be converted to 'one_two' and 'One/Two' to one_or_to
public static string To_Field_Name(string headerColumn)
{
string result = Regex.Replace(headerColumn.ToLower(), @"\s*(/)+\s*", "_or_");
return Regex.Replace(result, @"[\s*]", "_");
}
public static string To_Header_Column(string fieldName)
{
string result = Regex.Replace(fieldName, @"_or_", "/");
return Regex.Replace(result.ToUpper(), @"_", " ");
}
}
private static string GetColumnValue(TableCell cell)
{
string value = cell.Value.ToString();
return "(null)".Equals(value) ? null : value;
}
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class ScreenIgnoreAttribute : Attribute {}
}