@@ -13,6 +13,112 @@ namespace DocumentFormat.OpenXml.Generator.Generators.Elements;
13
13
14
14
public static class DataModelWriterExtensions
15
15
{
16
+ public static class AttributeStrings
17
+ {
18
+ public const string ObsoletePropertyWarn = "[Obsolete(\" Unused property, will be removed in a future version.\" , false)]" ;
19
+ public const string ObsoletePropertyError = "[Obsolete(\" Unused property, will be removed in a future version.\" , true)]" ;
20
+ public const string ObsoleteAttributeWarn = "[Obsolete(\" Unused attribute, will be removed in a future version.\" , false)]" ;
21
+ public const string ObsoleteAttributeError = "[Obsolete(\" Unused attribute, will be removed in a future version.\" , true)]" ;
22
+ public const string EditorBrowsableAlways = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)] " ;
23
+ public const string EditorBrowsableAdvanced = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)] " ;
24
+ public const string EditorBrowsableNever = "[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] " ;
25
+ }
26
+
27
+ private static readonly List < string > ObsoletePropertyWarnList =
28
+ [
29
+ AttributeStrings . ObsoletePropertyWarn ,
30
+ AttributeStrings . EditorBrowsableNever ,
31
+ ] ;
32
+
33
+ // Use this dictionary to add attributes like ObsoleteAttribute or other directives to classes, child elements or attributes.
34
+ private static readonly Dictionary < TypedQName , Dictionary < TypedQName , List < string > > > _attributeData =
35
+ new Dictionary < TypedQName , Dictionary < TypedQName , List < string > > > ( )
36
+ {
37
+ // Example with annotations:
38
+ // {
39
+ // This is the containing complex type class, in the json metadata, this comes from the fully qualified "Name": "c:CT_BubbleSer/c15:ser",
40
+ // "c:CT_BubbleSer/c15:ser",
41
+ // new Dictionary<TypedQName, List<string>>()
42
+ // {
43
+ // {
44
+ // This is an example of obsoleting the whole class.
45
+ // In the json metadata:
46
+ // Use the same fully qualified name as the class, for example "Name": "c:CT_BubbleSer/c15:ser",
47
+ // "c:CT_BubbleSer/c15:ser",
48
+ // ObsoleteClassErrorList
49
+ // },
50
+ // {
51
+ // This is an example obsoleting a child element (property in C#)
52
+ // In the json metadata:
53
+ // For child elements, this comes from "Name": "c:CT_PictureOptions/c:pictureOptions",
54
+ // "c:CT_PictureOptions/c:pictureOptions",
55
+ // ObsoletePropertyWarnList
56
+ // },
57
+ // {
58
+ // This is an example obsoleting a child attribute (property in C#)
59
+ // In the json metadata: use for example "QName" converted to a TypedQName string using the C# type from the
60
+ // Type property with no prefix: ":StringValue/:formatCode",
61
+ // ":StringValue/:formatCode",
62
+ // ObsoleteAttributeWarnList
63
+ // },
64
+ // }
65
+ // },
66
+ {
67
+ "c:CT_BubbleSer/c15:ser" ,
68
+ new Dictionary < TypedQName , List < string > > ( )
69
+ {
70
+ {
71
+ "c:CT_PictureOptions/c:pictureOptions" ,
72
+ ObsoletePropertyWarnList
73
+ } ,
74
+ }
75
+ } ,
76
+ {
77
+ "c:CT_LineSer/c15:ser" ,
78
+ new Dictionary < TypedQName , List < string > > ( )
79
+ {
80
+ {
81
+ "c:CT_PictureOptions/c:pictureOptions" ,
82
+ ObsoletePropertyWarnList
83
+ } ,
84
+ }
85
+ } ,
86
+ {
87
+ "c:CT_PieSer/c15:ser" ,
88
+ new Dictionary < TypedQName , List < string > > ( )
89
+ {
90
+ {
91
+ "c:CT_PictureOptions/c:pictureOptions" ,
92
+ ObsoletePropertyWarnList
93
+ } ,
94
+ }
95
+ } ,
96
+ {
97
+ "c:CT_RadarSer/c15:ser" ,
98
+ new Dictionary < TypedQName , List < string > > ( )
99
+ {
100
+ {
101
+ "c:CT_PictureOptions/c:pictureOptions" ,
102
+ ObsoletePropertyWarnList
103
+ } ,
104
+ }
105
+ } ,
106
+ {
107
+ "c:CT_SurfaceSer/c15:ser" ,
108
+ new Dictionary < TypedQName , List < string > > ( )
109
+ {
110
+ {
111
+ "c:CT_PictureOptions/c:pictureOptions" ,
112
+ ObsoletePropertyWarnList
113
+ } ,
114
+ {
115
+ "c:CT_Boolean/c:bubble3D" ,
116
+ ObsoletePropertyWarnList
117
+ } ,
118
+ }
119
+ } ,
120
+ } ;
121
+
16
122
public static bool GetDataModelSyntax ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaNamespace model )
17
123
{
18
124
foreach ( var ns in GetNamespaces ( model , services ) . Distinct ( ) . OrderBy ( n => n ) )
@@ -84,6 +190,20 @@ private static void WriteTypeDetails(this IndentedTextWriter writer, OpenXmlGene
84
190
private static void WriteType ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType element )
85
191
{
86
192
writer . WriteDocumentationComment ( BuildTypeComments ( services , element ) ) ;
193
+
194
+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > ctAttributeData ) )
195
+ {
196
+ // if the fully qualified CT/tag name is also one of the children of the dictionary that means the attributes of that
197
+ // child's list need to be applied to the whole class, for example, if we're obsoleting an entire class.
198
+ if ( ctAttributeData . TryGetValue ( element . Name , out List < string > attributeStrings ) )
199
+ {
200
+ foreach ( string attributeString in attributeStrings )
201
+ {
202
+ writer . WriteLine ( attributeString ) ;
203
+ }
204
+ }
205
+ }
206
+
87
207
writer . Write ( "public " ) ;
88
208
89
209
if ( element . IsAbstract )
@@ -122,7 +242,16 @@ private static void WriteType(this IndentedTextWriter writer, OpenXmlGeneratorSe
122
242
foreach ( var attribute in element . Attributes )
123
243
{
124
244
delimiter . AddDelimiter ( ) ;
125
- writer . WriteAttributeProperty ( services , attribute ) ;
245
+
246
+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > attrAttributeData )
247
+ && attrAttributeData . TryGetValue ( ":" + attribute . Type + "/" + attribute . QName . ToString ( ) , out List < string > attrAttributeStrings ) )
248
+ {
249
+ writer . WriteAttributeProperty ( services , attribute , attrAttributeStrings ) ;
250
+ }
251
+ else
252
+ {
253
+ writer . WriteAttributeProperty ( services , attribute ) ;
254
+ }
126
255
}
127
256
128
257
delimiter . AddDelimiter ( ) ;
@@ -132,7 +261,15 @@ private static void WriteType(this IndentedTextWriter writer, OpenXmlGeneratorSe
132
261
{
133
262
foreach ( var node in element . Children )
134
263
{
135
- writer . WriteElement ( services , element , node , ref delimiter ) ;
264
+ if ( _attributeData . TryGetValue ( element . Name , out Dictionary < TypedQName , List < string > > childAttributeData )
265
+ && childAttributeData . TryGetValue ( node . Name , out List < string > childAttributeStrings ) )
266
+ {
267
+ writer . WriteElement ( services , element , node , ref delimiter , childAttributeStrings ) ;
268
+ }
269
+ else
270
+ {
271
+ writer . WriteElement ( services , element , node , ref delimiter ) ;
272
+ }
136
273
}
137
274
}
138
275
@@ -318,7 +455,7 @@ void WriteUnion(IndentedTextWriter writer, string name, IEnumerable<Validator> v
318
455
}
319
456
}
320
457
321
- private static void WriteElement ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType parent , SchemaElement element , ref Delimiter delimiter )
458
+ private static void WriteElement ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaType parent , SchemaElement element , ref Delimiter delimiter , List < string > ? attributeStrings = null )
322
459
{
323
460
if ( string . IsNullOrEmpty ( element . PropertyName ) )
324
461
{
@@ -340,6 +477,14 @@ private static void WriteElement(this IndentedTextWriter writer, OpenXmlGenerato
340
477
Remarks = $ "xmlns:{ element . Name . QName . Prefix } = { services . GetNamespaceInfo ( element . Name . QName . Prefix ) . Uri } ",
341
478
} ) ;
342
479
480
+ if ( attributeStrings is not null )
481
+ {
482
+ foreach ( string attributeString in attributeStrings )
483
+ {
484
+ writer . WriteLine ( attributeString ) ;
485
+ }
486
+ }
487
+
343
488
writer . Write ( "public " ) ;
344
489
writer . Write ( className ) ;
345
490
writer . Write ( "? " ) ;
@@ -377,7 +522,7 @@ internal static void WriteTypedName(this IndentedTextWriter writer, OpenXmlGener
377
522
writer . Write ( ")" ) ;
378
523
}
379
524
380
- private static void WriteAttributeProperty ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaAttribute attribute )
525
+ private static void WriteAttributeProperty ( this IndentedTextWriter writer , OpenXmlGeneratorServices services , SchemaAttribute attribute , List < string > ? attributeStrings = null )
381
526
{
382
527
var remarks = default ( string ) ;
383
528
var info = services . GetNamespaceInfo ( attribute . QName . Prefix ) ;
@@ -401,6 +546,14 @@ private static void WriteAttributeProperty(this IndentedTextWriter writer, OpenX
401
546
Remarks = remarks ,
402
547
} ) ;
403
548
549
+ if ( attributeStrings is not null )
550
+ {
551
+ foreach ( string attributeString in attributeStrings )
552
+ {
553
+ writer . WriteLine ( attributeString ) ;
554
+ }
555
+ }
556
+
404
557
writer . Write ( "public " ) ;
405
558
writer . Write ( attribute . Type ) ;
406
559
writer . Write ( "? " ) ;
0 commit comments