@@ -11,6 +11,112 @@ namespace DocumentFormat.OpenXml.Generator.Generators.Elements;
11
11
12
12
public static class DataModelWriterExtensions
13
13
{
14
+ public static class AttributeStrings
15
+ {
16
+ public const string ObsoletePropertyWarn = "[Obsolete(\" Unused property, will be removed in a future version.\" , false)]" ;
17
+ public const string ObsoletePropertyError = "[Obsolete(\" Unused property, will be removed in a future version.\" , true)]" ;
18
+ public const string ObsoleteAttributeWarn = "[Obsolete(\" Unused attribute, will be removed in a future version.\" , false)]" ;
19
+ public const string ObsoleteAttributeError = "[Obsolete(\" Unused attribute, will be removed in a future version.\" , true)]" ;
20
+ public const string EditorBrowsableAlways = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)] " ;
21
+ public const string EditorBrowsableAdvanced = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)] " ;
22
+ public const string EditorBrowsableNever = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] " ;
23
+ }
24
+
25
+ private static readonly List < string > ObsoletePropertyWarnList =
26
+ [
27
+ AttributeStrings . ObsoletePropertyWarn ,
28
+ AttributeStrings . EditorBrowsableNever ,
29
+ ] ;
30
+
31
+ // Use this dictionary to add attributes like ObsoleteAttribute or other directives to classes, child elements or attributes.
32
+ private static readonly Dictionary < TypedQName , Dictionary < TypedQName , List < string > > > _attributeData =
33
+ new Dictionary < TypedQName , Dictionary < TypedQName , List < string > > > ( )
34
+ {
35
+ // Example with annotations:
36
+ // {
37
+ // This is the containing complex type class, in the json metadata, this comes from the fully qualified "Name": "c:CT_BubbleSer/c15:ser",
38
+ // "c:CT_BubbleSer/c15:ser",
39
+ // new Dictionary<TypedQName, List<string>>()
40
+ // {
41
+ // {
42
+ // This is an example of obsoleting the whole class.
43
+ // In the json metadata:
44
+ // Use the same fully qualified name as the class, for example "Name": "c:CT_BubbleSer/c15:ser",
45
+ // "c:CT_BubbleSer/c15:ser",
46
+ // ObsoleteClassErrorList
47
+ // },
48
+ // {
49
+ // This is an example obsoleting a child element (property in C#)
50
+ // In the json metadata:
51
+ // For child elements, this comes from "Name": "c:CT_PictureOptions/c:pictureOptions",
52
+ // "c:CT_PictureOptions/c:pictureOptions",
53
+ // ObsoletePropertyWarnList
54
+ // },
55
+ // {
56
+ // This is an example obsoleting a child attribute (property in C#)
57
+ // In the json metadata: use for example "QName" converted to a TypedQName string using the C# type from the
58
+ // Type property with no prefix: ":StringValue/:formatCode",
59
+ // ":StringValue/:formatCode",
60
+ // ObsoleteAttributeWarnList
61
+ // },
62
+ // }
63
+ // },
64
+ {
65
+ "c:CT_BubbleSer/c15:ser" ,
66
+ new Dictionary < TypedQName , List < string > > ( )
67
+ {
68
+ {
69
+ "c:CT_PictureOptions/c:pictureOptions" ,
70
+ ObsoletePropertyWarnList
71
+ } ,
72
+ }
73
+ } ,
74
+ {
75
+ "c:CT_LineSer/c15:ser" ,
76
+ new Dictionary < TypedQName , List < string > > ( )
77
+ {
78
+ {
79
+ "c:CT_PictureOptions/c:pictureOptions" ,
80
+ ObsoletePropertyWarnList
81
+ } ,
82
+ }
83
+ } ,
84
+ {
85
+ "c:CT_PieSer/c15:ser" ,
86
+ new Dictionary < TypedQName , List < string > > ( )
87
+ {
88
+ {
89
+ "c:CT_PictureOptions/c:pictureOptions" ,
90
+ ObsoletePropertyWarnList
91
+ } ,
92
+ }
93
+ } ,
94
+ {
95
+ "c:CT_RadarSer/c15:ser" ,
96
+ new Dictionary < TypedQName , List < string > > ( )
97
+ {
98
+ {
99
+ "c:CT_PictureOptions/c:pictureOptions" ,
100
+ ObsoletePropertyWarnList
101
+ } ,
102
+ }
103
+ } ,
104
+ {
105
+ "c:CT_SurfaceSer/c15:ser" ,
106
+ new Dictionary < TypedQName , List < string > > ( )
107
+ {
108
+ {
109
+ "c:CT_PictureOptions/c:pictureOptions" ,
110
+ ObsoletePropertyWarnList
111
+ } ,
112
+ {
113
+ "c:CT_Boolean/c:bubble3D" ,
114
+ ObsoletePropertyWarnList
115
+ } ,
116
+ }
117
+ } ,
118
+ } ;
119
+
14
120
public static bool GetDataModelSyntax ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaNamespace model )
15
121
{
16
122
foreach ( var ns in GetNamespaces ( model , services ) . Distinct ( ) . OrderBy ( n => n ) )
@@ -66,6 +172,20 @@ private static string GetBaseName(SchemaType type)
66
172
private static void WriteType ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType element )
67
173
{
68
174
writer . WriteDocumentationComment ( BuildTypeComments ( services , element ) ) ;
175
+
176
+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > ctAttributeData ) )
177
+ {
178
+ // if the fully qualified CT/tag name is also one of the children of the dictionary that means the attributes of that
179
+ // child's list need to be applied to the whole class, for example, if we're obsoleting an entire class.
180
+ if ( ctAttributeData . TryGetValue ( element . Name , out List < string > attributeStrings ) )
181
+ {
182
+ foreach ( string attributeString in attributeStrings )
183
+ {
184
+ writer . WriteLine ( attributeString ) ;
185
+ }
186
+ }
187
+ }
188
+
69
189
writer . Write ( "public " ) ;
70
190
71
191
if ( element . IsAbstract )
@@ -100,7 +220,16 @@ private static void WriteType(this IndentedTextWriter writer, OpenXmlGeneratorSe
100
220
foreach ( var attribute in element . Attributes )
101
221
{
102
222
delimiter . AddDelimiter ( ) ;
103
- writer . WriteAttributeProperty ( services , attribute ) ;
223
+
224
+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > attrAttributeData )
225
+ && attrAttributeData . TryGetValue ( ":" + attribute . Type + "/" + attribute . QName . ToString ( ) , out List < string > attrAttributeStrings ) )
226
+ {
227
+ writer . WriteAttributeProperty ( services , attribute , attrAttributeStrings ) ;
228
+ }
229
+ else
230
+ {
231
+ writer . WriteAttributeProperty ( services , attribute ) ;
232
+ }
104
233
}
105
234
106
235
delimiter . AddDelimiter ( ) ;
@@ -110,7 +239,15 @@ private static void WriteType(this IndentedTextWriter writer, OpenXmlGeneratorSe
110
239
{
111
240
foreach ( var node in element . Children )
112
241
{
113
- writer . WriteElement ( services , element , node , ref delimiter ) ;
242
+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > childAttributeData )
243
+ && childAttributeData . TryGetValue ( node . Name , out List < string > childAttributeStrings ) )
244
+ {
245
+ writer . WriteElement ( services , element , node , ref delimiter , childAttributeStrings ) ;
246
+ }
247
+ else
248
+ {
249
+ writer . WriteElement ( services , element , node , ref delimiter ) ;
250
+ }
114
251
}
115
252
}
116
253
@@ -298,7 +435,7 @@ void WriteUnion(IndentedTextWriter writer, string name, IEnumerable<Validator> v
298
435
}
299
436
}
300
437
301
- private static void WriteElement ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType parent , SchemaElement element , ref Delimiter delimiter )
438
+ private static void WriteElement ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType parent , SchemaElement element , ref Delimiter delimiter , List < string > ? attributeStrings = null )
302
439
{
303
440
if ( string . IsNullOrEmpty ( element . PropertyName ) )
304
441
{
@@ -320,6 +457,14 @@ private static void WriteElement(this IndentedTextWriter writer, OpenXmlGenerato
320
457
Remarks = $ "xmlns:{ element . Name . QName . Prefix } = { services . GetNamespaceInfo ( element . Name . QName . Prefix ) . Uri } ",
321
458
} ) ;
322
459
460
+ if ( attributeStrings is not null )
461
+ {
462
+ foreach ( string attributeString in attributeStrings )
463
+ {
464
+ writer . WriteLine ( attributeString ) ;
465
+ }
466
+ }
467
+
323
468
writer . Write ( "public " ) ;
324
469
writer . Write ( className ) ;
325
470
writer . Write ( "? " ) ;
@@ -335,7 +480,7 @@ private static void WriteElement(this IndentedTextWriter writer, OpenXmlGenerato
335
480
}
336
481
}
337
482
338
- private static void WriteAttributeProperty ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaAttribute attribute )
483
+ private static void WriteAttributeProperty ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaAttribute attribute , List < string > ? attributeStrings = null )
339
484
{
340
485
var remarks = default ( string ) ;
341
486
var info = services . GetNamespaceInfo ( attribute . QName . Prefix ) ;
@@ -359,6 +504,14 @@ private static void WriteAttributeProperty(this IndentedTextWriter writer, OpenX
359
504
Remarks = remarks ,
360
505
} ) ;
361
506
507
+ if ( attributeStrings is not null )
508
+ {
509
+ foreach ( string attributeString in attributeStrings )
510
+ {
511
+ writer . WriteLine ( attributeString ) ;
512
+ }
513
+ }
514
+
362
515
writer . Write ( "public " ) ;
363
516
writer . Write ( attribute . Type ) ;
364
517
writer . Write ( "? " ) ;
0 commit comments