1
+ using System ;
2
+ using System . CodeDom ;
3
+ using System . Collections . Generic ;
4
+ using System . ComponentModel ;
5
+ using System . Xml . Serialization ;
6
+
7
+ namespace NHibernate . Tool . HbmXsd
8
+ {
9
+ /// <summary>
10
+ /// Responsible for improving the enum field names in code generated by an
11
+ /// <see cref="XsdCodeGenerator" />.
12
+ /// </summary>
13
+ public class ImproveEnumFieldsCommand
14
+ {
15
+ private readonly Dictionary < string , Dictionary < string , string > > changedEnums =
16
+ new Dictionary < string , Dictionary < string , string > > ( ) ;
17
+
18
+ private readonly CodeNamespace code ;
19
+
20
+ public ImproveEnumFieldsCommand ( CodeNamespace code )
21
+ {
22
+ if ( code == null )
23
+ throw new ArgumentNullException ( "code" ) ;
24
+
25
+ this . code = code ;
26
+ }
27
+
28
+ /// <summary>Changes enum field names to use camel casing.</summary>
29
+ public void Execute ( )
30
+ {
31
+ ChangeDeclaredEnumFields ( ) ;
32
+ UpdateReferences ( ) ;
33
+ }
34
+
35
+ private void ChangeDeclaredEnumFields ( )
36
+ {
37
+ foreach ( CodeTypeDeclaration type in code . Types )
38
+ if ( type . IsEnum )
39
+ {
40
+ changedEnums [ type . Name ] = new Dictionary < string , string > ( ) ;
41
+
42
+ foreach ( CodeTypeMember member in type . Members )
43
+ {
44
+ string xmlEnumValue = GetXmlEnumValue ( member ) ;
45
+ string newEnumName = GetNewEnumName ( type . Name , member . Name , xmlEnumValue ) ;
46
+ changedEnums [ type . Name ] [ member . Name ] = newEnumName ;
47
+ member . Name = newEnumName ;
48
+ }
49
+ }
50
+ }
51
+
52
+ private void UpdateReferences ( )
53
+ {
54
+ foreach ( CodeTypeDeclaration type in code . Types )
55
+ if ( type . IsClass )
56
+ foreach ( CodeTypeMember member in type . Members )
57
+ {
58
+ CodeMemberField field = member as CodeMemberField ;
59
+ CodeConstructor constructor = member as CodeConstructor ;
60
+
61
+ if ( field != null )
62
+ UpdateFieldEnumValueReferences ( field ) ;
63
+
64
+ else if ( constructor != null )
65
+ UpdateMethodEnumValueReferences ( constructor ) ;
66
+ }
67
+ }
68
+
69
+ private static string GetXmlEnumValue ( CodeTypeMember member )
70
+ {
71
+ if ( member . CustomAttributes . Count == 1 )
72
+ {
73
+ CodeAttributeArgument argument = member . CustomAttributes [ 0 ] . Arguments [ 0 ] ;
74
+ return ( ( CodePrimitiveExpression ) argument . Value ) . Value . ToString ( ) ;
75
+ }
76
+ else
77
+ {
78
+ AddXmlEnumAttribute ( member ) ;
79
+ return null ;
80
+ }
81
+ }
82
+
83
+ protected virtual string GetNewEnumName ( string typeName , string memberName , string xmlEnumValue )
84
+ {
85
+ if ( xmlEnumValue != null )
86
+ return StringTools . CamelCase ( xmlEnumValue ) ;
87
+ else
88
+ return StringTools . CamelCase ( memberName ) ;
89
+ }
90
+
91
+ private static void AddXmlEnumAttribute ( CodeTypeMember member )
92
+ {
93
+ CodeTypeReference attributeType = new CodeTypeReference ( typeof ( XmlEnumAttribute ) ) ;
94
+ CodePrimitiveExpression argumentValue = new CodePrimitiveExpression ( member . Name ) ;
95
+ CodeAttributeArgument argument = new CodeAttributeArgument ( argumentValue ) ;
96
+ CodeAttributeDeclaration attribute = new CodeAttributeDeclaration ( attributeType , argument ) ;
97
+
98
+ member . CustomAttributes . Add ( attribute ) ;
99
+ }
100
+
101
+ private void UpdateFieldEnumValueReferences ( CodeTypeMember field )
102
+ {
103
+ foreach ( CodeAttributeDeclaration attribute in field . CustomAttributes )
104
+ if ( attribute . Name == typeof ( DefaultValueAttribute ) . FullName )
105
+ {
106
+ CodeFieldReferenceExpression reference = attribute . Arguments [ 0 ] . Value
107
+ as CodeFieldReferenceExpression ;
108
+
109
+ if ( reference != null )
110
+ UpdateReference ( reference ) ;
111
+ }
112
+ }
113
+
114
+ private void UpdateMethodEnumValueReferences ( CodeMemberMethod method )
115
+ {
116
+ foreach ( CodeStatement statement in method . Statements )
117
+ {
118
+ CodeAssignStatement assignment = ( CodeAssignStatement ) statement ;
119
+ CodeFieldReferenceExpression right = assignment . Right as CodeFieldReferenceExpression ;
120
+
121
+ if ( right != null )
122
+ UpdateReference ( right ) ;
123
+ }
124
+ }
125
+
126
+ private void UpdateReference ( CodeFieldReferenceExpression reference )
127
+ {
128
+ string type = ( ( CodeTypeReferenceExpression ) reference . TargetObject ) . Type . BaseType ;
129
+
130
+ if ( changedEnums [ type ] . ContainsKey ( reference . FieldName ) )
131
+ reference . FieldName = changedEnums [ type ] [ reference . FieldName ] ;
132
+ }
133
+ }
134
+ }
0 commit comments