-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathOutputLanguageCS.vb
More file actions
executable file
·1711 lines (1448 loc) · 85.1 KB
/
Copy pathOutputLanguageCS.vb
File metadata and controls
executable file
·1711 lines (1448 loc) · 85.1 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Imports System.Text.RegularExpressions
Imports System.Windows.Forms.Control
Imports System.Xml
Imports System.IO
Public Class OutputLanguageCS
Implements IOutputLanguage
Private Enum EA_TYPE ' these are EA types (see the EA help topic "Type" which have been inferred by trial and error
FINAL_STATE = 4
EXIT_STATE = 14
INITIAL_STATE = 3
ENTRY_STATE = 13
TERMINATE_STATE = 12
SYNCH_STATE = 6
End Enum
Private Const CONSTANTS_COLUMN = 90
Private Const COLUMN_WIDTH As Integer = 55
'Private Const DEFAULT_INSTANCE_ALLOCATION As Integer = 14
'Private Const INSTANCE_POINTER_ARRAY_COUNT As Integer = DEFAULT_INSTANCE_ALLOCATION ' specifies the number of slots allocated to the array of pointers used to formalize x:M relationships
Private Shared _ModelEnumerations As SortedDictionary(Of String, EA.Element) ' a collection of *all* enumerations found in the model (using a hashtable to be sure name-order is always the same)
Private Shared _SortedEnumeratorNames As List(Of String)
Private Shared _ModelDataTypes As Collection ' a collection of *all* data types found in the model
Private Shared _oRelationshipNames As Collection
Private Shared _iPackageCount As Integer = 0
Private Shared _oRelatesConnectorNamesC As Collection
Private Shared _oRelatesConnectorNamesH As Collection
Private Shared _OutputTabName As String = "EA Compiler"
Private Shared _Repository As EA.Repository
Private Shared _Project As EA.Project
Public Shared ModelEventNames As Collection
Public Shared DomainEventNames As Collection
Public Shared Sub ShowOutputLine(sOutputLine As String)
_Repository.WriteOutput(_OutputTabName, " " + sOutputLine, 0)
End Sub
Public Sub CreateDomains(ByVal oRepository As EA.Repository, ByVal bIncludeDebug As Boolean, ByVal sXSLfilename As String, ByVal sOutputFileExtension As String) Implements IOutputLanguage.CreateDomains
Try
_Project = oRepository.GetProjectInterface()
_Repository = oRepository
_ModelEnumerations = New SortedDictionary(Of String, EA.Element)
_ModelDataTypes = New Collection
_oRelationshipNames = New Collection
_oRelatesConnectorNamesC = New Collection
_oRelatesConnectorNamesH = New Collection
ModelEventNames = New Collection
oRepository.CreateOutputTab(_OutputTabName)
oRepository.EnsureOutputVisible(_OutputTabName)
ShowOutputLine("B e g i n C o m p l i a t i o n")
Dim oPackagesList As New Collection
For Each oPackage As EA.Package In oRepository.Models.GetAt(0).Packages
recursePackage(oPackage, oPackagesList)
Next
If _iPackageCount = 0 Then
MsgBox("No packages found with stereotype 'cs' so no compilation was done")
Else
For Each oFoundPackage As EA.Package In oPackagesList
createDomain(oRepository, oFoundPackage, bIncludeDebug)
Next
End If
createEnumerationsFile(oRepository)
'gStatusBox.FadeAway()
PlaySound("TortoiseSVN_Notification.wav", 0, SND_FILENAME)
ShowOutputLine("E n d C o m p l i a t i o n")
ShowOutputLine(" ")
Catch ex As Exception
Dim oErrorHandler As New sjmErrorHandler(ex)
End Try
End Sub
Public Shared Function CanonicalType(ByVal sType As String) As String
sType = sType.Trim
Dim sReturnTypeString As String = sType
If sType.Length > 0 Then
Select Case sType.ToLower
Case "boolean", "bool"
sReturnTypeString = "bool"
Case "void"
sReturnTypeString = "void"
Case "unsigned long"
sReturnTypeString = "long"
Case "byte", "unsigned char"
sReturnTypeString = "byte"
Case "int"
sReturnTypeString = "int"
Case "char"
sReturnTypeString = "string"
Case "float", "double"
sReturnTypeString = "float"
Case "string", "char*"
sReturnTypeString = "string"
End Select
End If
Return Canonical.CanonicalName(sReturnTypeString)
End Function
Private Sub recursePackage(ByVal oNextPackage As EA.Package, ByVal oPackages As Collection)
For Each oPackage As EA.Package In oNextPackage.Packages
If PackageIncludesStereotype(oPackage, "cs") Then
_iPackageCount += 1
oPackages.Add(oPackage)
End If
recursePackage(oPackage, oPackages)
Next
End Sub
Private Sub createEnumerationsFile(ByVal oRepository As EA.Repository)
If _ModelEnumerations.Values.Count > 0 Then
Dim sOutputFilename As String = Path.Combine(Path.GetDirectoryName(oRepository.ConnectionString), "Enumerations")
Dim oDataTypesFileCS As OutputFile = New OutputFile(sOutputFilename + ".cs", True)
With oDataTypesFileCS
.Add()
.Add("//________________________________________________________________________________")
.Add("//")
.Add("// THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT IT DIRECTLY")
.Add("//________________________________________________________________________________")
.Add("//")
.Add("// File: " & sOutputFilename & ".cs")
.Add("//")
.Add("// Created by: " & Application.ProductName & " (EA Model Compiler v" & VERSION & ")")
.Add("//")
.Add("// Generated: " & Now.ToLongDateString & ", " & Now.ToLongTimeString)
.Add("//")
.Add("//________________________________________________________________________________")
.Add("")
.Add("using System.Collections;")
.Add("")
addEnumeratorsCS(oDataTypesFileCS)
.Add("")
.Close()
End With
End If
End Sub
Private Sub addEnumeratorsCS(ByVal oEnumerationsFileC As OutputFile)
Dim oEnumeration As EA.Element
With oEnumerationsFileC
.Add("public class Enumerations")
.Add("{")
For Each oEnumeration In _ModelEnumerations.Values
If oEnumeration.Attributes.Count > 0 Then
.Add("")
.Add(" public enum " + Canonical.CanonicalName(oEnumeration.Name))
.Add(" {")
Dim iEnumeratorCount As Integer = 0
_SortedEnumeratorNames = New List(Of String)
Dim NoteStrings As List(Of String) = New List(Of String)
For Each oEnumerator As EA.Attribute In oEnumeration.Attributes
oEnumerator.Name = Canonical.CanonicalName(oEnumerator.Name)
Dim sComment As String = CleanNoteString(oEnumerator)
If sComment.Length > 0 Then
sComment = "// " & sComment
End If
_SortedEnumeratorNames.Add(" " + oEnumeration.Name + "_" + (oEnumerator.Name + " = ZZZ, ").PadRight(70) + sComment) ' leave a ZZZ marker for the ordinal value after sorting
Next
_SortedEnumeratorNames.Sort()
For Each sEnumeratorName As String In _SortedEnumeratorNames
.Add(sEnumeratorName.Replace("ZZZ", iEnumeratorCount.ToString)) ' tuck the ordinal value into the pre-built string
iEnumeratorCount += 1
Next
.Add(" }")
End If
Next
.Add("")
.Add("")
For Each oEnumeration In _ModelEnumerations.Values
If oEnumeration.Attributes.Count > 0 Then
.Add(" static private Hashtable " + oEnumeration.Name + "_Descriptions; ")
.Add(" static public string Get_" + oEnumeration.Name + "_Description(" + oEnumeration.Name + " ID) ")
.Add(" { ")
.Add(" string sDescription = ""illegal array index received = "" + ID.ToString() + "" for array '" + oEnumeration.Name + "'""; ")
.Add(" if (" + oEnumeration.Name + "_Descriptions == null) ")
.Add(" { ")
.Add(" " + oEnumeration.Name + "_Descriptions = new Hashtable(); ")
For Each oEnumerator As EA.Attribute In oEnumeration.Attributes
.Add(" " + oEnumeration.Name + "_Descriptions.Add((long)" + oEnumeration.Name + "." + oEnumeration.Name + "_" + Canonical.CanonicalName(oEnumerator.Name) + ", """ + CleanNoteString(oEnumerator) + """); ")
Next
.Add(" } ")
.Add(" ")
.Add(" if(" + oEnumeration.Name + "_Descriptions.Contains((long)ID)) ")
.Add(" { ")
.Add(" sDescription = (string)" + oEnumeration.Name + "_Descriptions[(long)ID]; ")
.Add(" } ")
.Add(" ")
.Add(" ")
.Add(" return sDescription; ")
.Add(" } ")
.Add(vbCrLf)
End If
Next
.Add("")
.Add("")
.Add("}")
End With
End Sub
Private Sub addEnumerators(ByVal oDataTypesFileC As OutputFile)
Dim oEnumeration As EA.Element
With oDataTypesFileC
For Each oEnumeration In _ModelEnumerations.Values
If oEnumeration.Attributes.Count > 0 Then
.Add(" static char* " + oEnumeration.Name + "_Descriptions[" + oEnumeration.Attributes.Count.ToString + "] = ")
.Add(" {")
For Each oEnumerator As EA.Attribute In oEnumeration.Attributes
.Add(" """ + CleanNoteString(oEnumerator) + " "",")
Next
.Add(" };")
.Add(vbCrLf)
End If
Next
.Add("")
.Add("")
For Each oEnumeration In _ModelEnumerations.Values
If oEnumeration.Attributes.Count > 0 Then
'Dim sFirstEnumeratorName As String = ""
'For Each oEnumerator As EA.Attribute In oEnumeration.Attributes
' sFirstEnumeratorName = oEnumerator.Name
' Exit For
'Next
.Add(" char* Get_" + oEnumeration.Name + "_Description(" + oEnumeration.Name + " ID)")
.Add(" {")
.Add(" return " + oEnumeration.Name + "_Descriptions[ID];")
.Add(" };")
.Add(vbCrLf)
End If
Next
.Add("")
.Add("")
End With
End Sub
Private Sub createOutputFile(ByVal sOutputFilename As String, ByRef sFileText As String, ByVal oDomain As Domain)
Dim sDomainName As String = oDomain.Name
If sFileText.Length > 0 Then
OutputFile.ClearFilesCreated()
Dim oOutputFile As OutputFile = New OutputFile(sOutputFilename, True)
With oOutputFile
.Add("// ________________________________________________________________________________")
.Add("// ")
.Add("// THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT IT DIRECTLY")
.Add("// ________________________________________________________________________________")
.Add("// ")
.Add("// File: " & sOutputFilename)
.Add("// ")
.Add("// Created by: " & Application.ProductName & " (EA Model Compiler v" & VERSION & ")")
.Add("// ")
.Add("// Generated: " & Now.ToLongDateString & ", " & Now.ToLongTimeString)
.Add("// ")
.Add("// ________________________________________________________________________________")
.Add("// ")
.Add("// Copyright © 2011, ArrayPower Inc. All rights reserved.")
.Add("// ________________________________________________________________________________")
.Add("")
.Add("")
.Add("using System;")
.Add("using System.IO;")
.Add("using System.Diagnostics;")
.Add("using System.Windows.Forms;")
.Add("using System.Collections.Generic;")
.Add("using System.IO.Ports;")
.Add("using System.Text.RegularExpressions;")
.Add("using System.Text;")
.Add("")
.Add("namespace " & oDomain.Name)
.Add("{")
addInstanceCollections(oOutputFile, oDomain)
.Add(sFileText)
addEventClasses(oOutputFile)
.Add("")
.Add(" public enum eEVENT")
.Add(" {")
Dim oUniqueNames As New Collection
For Each sEventName As String In ModelEventNames
Dim sTokens As String() = sEventName.Split(",")
If IsUnique(sTokens(0), oUniqueNames) Then
.Add(" " & sTokens(0) & ",")
End If
Next
.Add(" }")
.Add("")
.Add("}")
End With
oOutputFile.Close()
End If
End Sub
Private Sub addInstanceCollections(ByVal oOutputFile As OutputFile, ByVal oDomain As Domain)
With oOutputFile
.Add(" public class " & oDomain.Name)
.Add(" {")
For Each oEAClass As EA.Element In oDomain.ClassByID
If Not ElementIncludesStereotype(oEAClass, "omit") Then
.Add(" public static List<" & oEAClass.Name & "> " & oEAClass.Name & "s { get; set; }")
End If
Next
.Add(" }")
.Add("")
End With
End Sub
Private Sub addEventClasses(ByVal oOutputFile As OutputFile)
Dim oUniqueEventNames As New Collection
For Each sEventString As String In DomainEventNames
sEventString = Regex.Replace(sEventString, "[ ]+", " ")
Dim sTokens As String() = sEventString.Split(",")
Dim sArgumentString As String = ""
Dim sArgumentNamesOnlyString As String = ""
Dim sTypeArgPairDelimiter As String = ""
Dim sArgOnlyDelimiter As String = ""
Dim sEventName As String = sTokens(0)
If IsUnique(sEventName, oUniqueEventNames) Then
With oOutputFile
.Add("public class " & sEventName & " : ZEvent")
.Add("{")
For index As Integer = 0 To sTokens.Length - 1
sTokens(index) = sTokens(index).Trim()
Next
For index As Integer = 1 To sTokens.Length - 2
If sTokens(index).Length > 0 Then
.Add(" public " & sTokens(index) & " { get; set; }")
sArgumentString += sTypeArgPairDelimiter & sTokens(index)
sTypeArgPairDelimiter = ", "
End If
Next
.Add(" private void _" & sEventName & "(" & sArgumentString & ")")
.Add(" { ")
.Add(" EventID = (int)eEVENT." & sEventName & ";")
.Add(" Name = """ & sEventName & """;")
If sArgumentString.Length > 0 Then
sArgOnlyDelimiter = ""
For index As Integer = 1 To sTokens.Length - 2
Dim sTypeArgSplit As String() = sTokens(index).Split(" ")
.Add(" this." & sTypeArgSplit(1) & " = " & sTypeArgSplit(1) & "; // save the parameter value in local instance storage")
sArgumentNamesOnlyString += sArgOnlyDelimiter & sTypeArgSplit(1)
sArgOnlyDelimiter = ", "
Next
sArgumentString = ", " & sArgumentString
End If
.Add(" EventPump.EnqueueEvent(this);")
.Add(" }")
.Add("")
.Add(" public " & sEventName & "(ZClass oTargetInstance" & sArgumentString & ") ")
.Add(" : base(oTargetInstance) ")
.Add(" { ")
.Add(" _" & sEventName & "(" & sArgumentNamesOnlyString & "); ")
.Add(" } ")
.Add("")
.Add(" public " & sEventName & "(long lDelayMilliseconds, ZClass oTargetInstance" & sArgumentString & ") ")
.Add(" : base(oTargetInstance) ")
.Add(" { ")
.Add(" this.Delay_milliseconds = lDelayMilliseconds;")
.Add(" _" & sEventName & "(" & sArgumentNamesOnlyString & "); ")
.Add(" } ")
Dim sArgumentStringSansLeadingComma As String = ""
If sArgumentNamesOnlyString.Length > 0 Then
sArgumentStringSansLeadingComma = sArgumentString.Substring(1, sArgumentString.Length - 1)
sArgumentNamesOnlyString = ", " & sArgumentNamesOnlyString
End If
.Add("")
.Add(" // quick accessors")
.Add(" public static void Send(ZClass oTargetInstance" & sArgumentString & ") { " & sEventName & " oDummyEvent = new " & sEventName & "(oTargetInstance" & sArgumentNamesOnlyString & "); }")
.Add(" public static void Self(" & sArgumentStringSansLeadingComma & ") { " & sEventName & " oDummyEvent = new " & sEventName & "(ZClass.ActiveInstance" & sArgumentNamesOnlyString & "); }")
.Add(" public static void DelayedSelf(int iTicks" & sArgumentString & ") { " & sEventName & " oDummyEvent = new " & sEventName & "(iTicks, ZClass.ActiveInstance" & sArgumentNamesOnlyString & "); }")
.Add(" public static void Delayed(int iTicks, ZClass oTargetInstance" & sArgumentString & ") { " & sEventName & " oDummyEvent = new " & sEventName & "(iTicks, oTargetInstance" & sArgumentNamesOnlyString & "); }")
.Add("}" & vbCrLf)
End With
End If
Next
End Sub
Private Sub createDomain(ByVal oRepository As EA.Repository, ByVal oPackage As EA.Package, ByVal bIncludeDebug As Boolean)
Dim sOutputFilename As String = Path.Combine(Path.GetDirectoryName(oRepository.ConnectionString), Canonical.CanonicalName(oPackage.Name) & ".cs")
Dim oSourceOutout As New RichTextBox
'gStatusBox.Filename = oPackage.Name
oRepository.WriteOutput(_OutputTabName, " " + oPackage.Name, 0)
Dim oDomain As Domain = New Domain(oPackage, oRepository, oSourceOutout) ' constructor does the work
createOutputFile(sOutputFilename, oSourceOutout.Text, oDomain)
For Each oChildPackage As EA.Package In oPackage.Packages
createDomain(oRepository, oChildPackage, bIncludeDebug)
Next
End Sub
Protected Class Domain
Private _ClassById As Collection
Private _Triggers As Collection
Private _Enumerations As Collection
Private _DataTypes As Collection
Private _States As Collection
Private _Notes As Collection
Private _Boundarys As Collection
Private _StateMachines As Collection
Private _ObjectInstances As Collection
Private _Interfaces As Collection
Private _ElementById As Collection
Private _InitialStates As Collection
Private _FinalStates As Collection
Private _IgnoreIndicatorStates As Collection
Private _TestElements As Collection
Private _ParentChildren As Collection
Private _oExternals As Collection
Private _oTestFixtureElement As EA.Element
Private _oSourceOutput As RichTextBox
Private _oRepository As EA.Repository
Private _sPackageId As String
Private _oProject As EA.Project
Private _oPackage As EA.Package
Private _IsRealized As Boolean
Private _Name As String
Private _DiagramVersion As String
Private _DiagramNotes As String
Private _EAClassInstances As New List(Of EAClass)
Public ReadOnly Property EAClassInstances()
Get
Return _EAClassInstances
End Get
End Property
Public ReadOnly Property ClassByID() As Collection
Get
Return _ClassById
End Get
End Property
Public ReadOnly Property ParentChildren() As Collection
Get
Return _ParentChildren
End Get
End Property
Public ReadOnly Property Name() As String
Get
Return _Name
End Get
End Property
Public ReadOnly Property DiagramVersion() As String
Get
Return _DiagramVersion
End Get
End Property
Public ReadOnly Property DiagramNotes() As String
Get
Return _DiagramNotes
End Get
End Property
Public ReadOnly Property TestFixtureElement() As EA.Element
Get
Return _oTestFixtureElement
End Get
End Property
Public ReadOnly Property TestElements() As Collection
Get
Return _TestElements
End Get
End Property
Public ReadOnly Property Notes() As Collection
Get
Return _Notes
End Get
End Property
Public ReadOnly Property Repository() As EA.Repository
Get
Return _oRepository
End Get
End Property
Public ReadOnly Property Boundarys() As Collection
Get
Return _Boundarys
End Get
End Property
Public ReadOnly Property ObjectInstances() As Collection
Get
Return _ObjectInstances
End Get
End Property
Public ReadOnly Property Externals() As Collection
Get
Return _oExternals
End Get
End Property
Public ReadOnly Property StateMachines() As Collection
Get
Return _StateMachines
End Get
End Property
Public ReadOnly Property ElementById() As Collection
Get
Return _ElementById
End Get
End Property
Public ReadOnly Property States() As Collection
Get
Return _States
End Get
End Property
Public ReadOnly Property Triggers() As Collection
Get
Return _Triggers
End Get
End Property
Public ReadOnly Property EAClass(ByVal iID As Integer) As EA.Element
Get
Dim oClass As EA.Element = Nothing
If _ClassById.Contains(iID.ToString) Then
oClass = _ClassById.Item(iID.ToString)
Else
MsgBox("Unknown class id: " & iID, MsgBoxStyle.Critical)
End If
Return oClass
End Get
End Property
Public ReadOnly Property IsRealized() As Boolean
Get
Return _IsRealized
End Get
End Property
Public ReadOnly Property Package() As EA.Package
Get
Return _oPackage
End Get
End Property
Public Sub New(ByRef oPackage As EA.Package, ByRef oRepository As EA.Repository, ByRef oSourceOutput As RichTextBox)
Try
giNextStateID = oPackage.Name.GetHashCode
giNextEventID = giNextStateID
_oSourceOutput = oSourceOutput
_oRepository = oRepository
_oPackage = oPackage
_sPackageId = oPackage.PackageID
_Name = Canonical.CanonicalName(oPackage.Name)
_oTestFixtureElement = Nothing
DomainEventNames = New Collection
_DiagramNotes = ""
_DiagramVersion = "??"
If oPackage.Diagrams.Count > 0 Then
Dim oDiagram As EA.Diagram = oPackage.Diagrams.GetAt(0)
_DiagramNotes = oDiagram.Notes
_DiagramVersion = oDiagram.Version
_oExternals = New Collection
_Boundarys = New Collection
_Notes = New Collection
_ObjectInstances = New Collection
_TestElements = New Collection
_Interfaces = New Collection
_ClassById = New Collection
_Triggers = New Collection
_Enumerations = New Collection
_DataTypes = New Collection
_States = New Collection
_ElementById = New Collection
_StateMachines = New Collection
_InitialStates = New Collection
_FinalStates = New Collection
_IgnoreIndicatorStates = New Collection
_ParentChildren = New Collection
_IsRealized = PackageIncludesStereotype(_oPackage, "realized")
If Not _IsRealized Then
ShowOutputLine(" " + oPackage.Name)
catalogElements()
generateSource()
addDomainOperations()
End If
End If
Catch ex As Exception
Dim oErrorHandler As New sjmErrorHandler(ex)
End Try
End Sub
Private Sub addDomainOperations()
With _oSourceOutput
For Each oEAClass As EAClass In _EAClassInstances
oEAClass.AddClassOperations(True)
Next
End With
End Sub
Private Sub snip(ByVal sMyID As String, ByRef sAncestryString As String)
Dim sOrignalAncestryString As String = sAncestryString
sAncestryString = Regex.Replace(sAncestryString, "[,]*" + sMyID, "")
End Sub
Private Function matchIDs(ByVal sAncestryString1 As String, ByVal sAncestryString2 As String) As Boolean
Dim bMatch As Boolean = False
sAncestryString1 = Regex.Replace(sAncestryString1, "[,]+", " ") ' all double commas become single spaces
sAncestryString1 = Regex.Replace(sAncestryString1, "[ ]+", " ") ' all double spaces become singles
Dim sAncestry1Ids() = Split(sAncestryString1.Trim, " ")
sAncestryString2 = Regex.Replace(sAncestryString2, "[,]+", " ") ' all double commas become single spaces
sAncestryString2 = Regex.Replace(sAncestryString2, "[ ]+", " ") ' all double spaces become singles
Dim sAncestry2Ids() = Split(sAncestryString2.Trim, " ")
If (sAncestry1Ids.Length = sAncestry2Ids.Length) And _
(sAncestryString1.Length > 0) And _
(sAncestryString2.Length > 0) Then
Dim oComparisonCollection As New Collection
For Each sID1 As String In sAncestry1Ids ' first add all the ancestry 1 IDs
oComparisonCollection.Add(sID1, sID1)
Next
bMatch = True ' assume all will match
For Each sID2 As String In sAncestry2Ids ' next verify all the ancestry 2 IDs are represented
If Not oComparisonCollection.Contains(sID2) Then
bMatch = False ' any single failure is enough to bail out
Exit For
End If
Next
End If
Return bMatch
End Function
Private Function removeNonFamilyIDs(ByVal oFamily As Collection, ByVal oNonFamily As Collection) As Collection
Dim oFamilyMemberAncestry As New Collection ' we start with a complete set of ancestry IDs for these family members
For Each oFamilyMemberClass As EA.Element In oFamily
oFamilyMemberAncestry.Add(oFamilyMemberClass.GetRelationSet(EA.EnumRelationSetType.rsParents), oFamilyMemberClass.ElementID.ToString)
Next
For Each oNonFamilyMemberClass As EA.Element In oNonFamily
Dim sNonFamilyMemberClassID As String = oNonFamilyMemberClass.ElementID.ToString
For Each oFamilyMemberClass As EA.Element In oFamily
Dim sFamilyMemberID As String = oFamilyMemberClass.ElementID.ToString
Dim sFamilyMemberAncestry As String = oFamilyMemberAncestry(sFamilyMemberID)
oFamilyMemberAncestry.Remove(sFamilyMemberID)
snip(sNonFamilyMemberClassID, sFamilyMemberAncestry)
oFamilyMemberAncestry.Add(sFamilyMemberAncestry, sFamilyMemberID)
Next
Next
Return oFamilyMemberAncestry
End Function
Private Sub appendChild(ByVal oParentClass As EA.Element, ByVal oChildClass As EA.Element)
Dim oChildren As Collection
If Not _ParentChildren.Contains(oParentClass.ElementID.ToString) Then
oChildren = New Collection
_ParentChildren.Add(oChildren, oParentClass.ElementID.ToString) ' add this parent's child collection to the main collection
End If
oChildren = _ParentChildren(oParentClass.ElementID.ToString)
If Not oChildren.Contains(oChildClass.ElementID.ToString) Then
oChildren.Add(oChildClass, oChildClass.ElementID.ToString) ' add one child to this parent's child collection
End If
End Sub
Private Sub catalogElement(ByVal oElement As EA.Element)
Application.DoEvents()
Try
oElement.Name = CanonicalClassName(oElement.Name) ' establish safe names right off the bat (rather than sprinkling everywehre)
_ElementById.Add(oElement, oElement.ElementID) ' just as a debugging convenience, to look up any element from its id only
If oElement.Name.Length = 0 Then
oElement.Name = "NoName_" & oElement.ElementID
End If
Select Case oElement.MetaType
Case "Object"
_ObjectInstances.Add(oElement, oElement.ElementID)
Case "StateMachine"
_StateMachines.Add(oElement, oElement.ElementID)
Case "FinalState"
_FinalStates.Add(oElement, oElement.ElementID)
_States.Add(oElement, oElement.ElementID)
Case "Pseudostate"
Select Case oElement.Name
Case "Initial"
_InitialStates.Add(oElement, oElement.ElementID)
_States.Add(oElement, oElement.ElementID)
Case Else
_IgnoreIndicatorStates.Add(oElement, oElement.ElementID)
_States.Add(oElement, oElement.ElementID)
End Select
Case "Trigger"
_Triggers.Add(oElement, oElement.Name)
Case "StateNode"
_States.Add(oElement, oElement.ElementID)
Case "Enumeration"
_Enumerations.Add(oElement, oElement.ElementID)
_ModelEnumerations.Add(oElement.Name, oElement)
Case "DataType"
_DataTypes.Add(oElement, oElement.ElementID)
_ModelDataTypes.Add(oElement, oElement.ElementID)
Case "Class"
oElement.Name = CanonicalClassName(oElement.Name)
_ClassById.Add(oElement, oElement.ElementID)
Case "Interface"
oElement.Name = CanonicalClassName(oElement.Name)
_Interfaces.Add(oElement, oElement.ElementID)
Case "State"
oElement.Name = Canonical.CanonicalName(oElement.Name)
_States.Add(oElement, oElement.ElementID)
Case "Note", "Text"
' do nothing with these, just allow them without complaint
Case Else
Debug.WriteLine(oElement.Name & " is an unhandled metatype " & oElement.MetaType)
End Select
Catch ex As Exception
Dim oErrorHandler As New sjmErrorHandler
oErrorHandler.SupplementalInformation = "Catalog Elements (" & oElement.Name & ")"
oErrorHandler.Announce(ex)
End Try
For Each oSubElement As EA.Element In oElement.Elements
catalogElement(oSubElement) ' recurse down the element tree
Next
End Sub
Private Sub catalogElements()
Dim oElement As EA.Element = Nothing
Try
For Each oElement In _oPackage.Elements
catalogElement(oElement)
Next
Catch ex As Exception
Dim oErrorHandler As New sjmErrorHandler
oErrorHandler.SupplementalInformation = "Catalog Elements (" & oElement.Name & ")"
oErrorHandler.Announce(ex)
End Try
End Sub
Private Sub generateSource()
Dim oClassElement As EA.Element
Dim oEAClass As EAClass
Static iClassCounter As Integer = 0
Try
If (_ClassById.Count > 0) Or (_Enumerations.Count > 0) Or (_DataTypes.Count > 0) Then
Application.DoEvents()
With _oSourceOutput
If _oPackage.Notes.Length > 0 Then
.AppendText(" // " & _oPackage.Notes)
End If
.AppendText(vbCrLf)
'gStatusBox.ProgressValueMaximum = _ClassById.Count
For Each oClassElement In _ClassById
'gStatusBox.ProgressValue = iClassCounter
Application.DoEvents()
If _sPackageId = oClassElement.PackageID Then
If Not ElementIncludesStereotype(oClassElement, "DataType") Then ' classes with stereotype 'DataType' are just psuedo-types for use in the model
If ElementIncludesStereotype(oClassElement, "omit") Then
Debug.WriteLine("Omitting class (by stereotype 'omit'): " & oClassElement.Name)
Else
oEAClass = New EAClass(oClassElement, Me, _oSourceOutput)
_EAClassInstances.Add(oEAClass)
End If
End If
End If
iClassCounter += 1
Next
End With
End If
Catch ex As Exception
Dim oErrorHandler As New sjmErrorHandler(ex)
End Try
End Sub
End Class
Private Class EAClass
Private _oEAElement As EA.Element
Private _oSourceOutput As RichTextBox
Private _oDomain As Domain
Private _bFinalStateReported As Boolean = False
Private _sInitialState As String = ""
Private _bActiveClass As Boolean = False
Private _sParentClassName As String = ""
Private _bIsSupertype As Boolean
Private _bIsSubtype As Boolean
Private _oStateClassSequences As New Collection
Private _oChildrenCollection As Collection
Private _oEventNames As New List(Of String)
Private _oAssociationNames As New Collection
Public Sub New(ByVal oEAElement As EA.Element, ByRef oDomain As Domain, ByVal oSourceOutput As RichTextBox)
Dim bIsTestFixture As Boolean = False
Dim bIsTest As Boolean = False
Dim oStateNames As New Collection
Try
_oDomain = oDomain
_oSourceOutput = oSourceOutput
_oEAElement = oEAElement
'gStatusBox.ShowClassName(_oEAElement.Name)
ShowOutputLine(" " + _oEAElement.Name)
If _oDomain.TestFixtureElement IsNot Nothing Then
bIsTestFixture = (_oDomain.TestFixtureElement.Name = _oEAElement.Name)
End If
bIsTest = _oDomain.TestElements.Contains(_oEAElement.Name)
With _oSourceOutput
.AppendText(vbCrLf)
If Not (ElementIncludesStereotype(_oEAElement, "domain") Or ElementIncludesStereotype(_oEAElement, "external")) Then
insertSummary(_oSourceOutput, oEAElement.Notes)
.AppendText("//_______________________________________________________________________________________________" & vbCrLf)
.AppendText("//_______________________________________________________________________________________________" & vbCrLf)
.AppendText("public class " & _oEAElement.Name & " : " & parentSupertype() & vbCrLf)
.AppendText("{" & vbCrLf)
Dim iClassStateMachineID As Integer = getClassStateMachineID(_oEAElement)
For Each oState As EA.Element In _oDomain.States
If oState.ParentID = iClassStateMachineID Then
If oState.MetaType <> "Pseudostate" Then
.AppendText(" private static " & oState.Name & " o" & oState.Name & " = new " & oState.Name & "();" & vbCrLf)
oStateNames.Add(oState.Name)
End If
End If
Next
''Dim oAttributes As Collection = accumulateAttributes(_oEAElement)
''Dim oConnectors As Collection = accumulateConnectors(_oEAElement)
addStateMachine(oStateNames)
addAttributes()
AddClassOperations(False) ' add all the operations
.AppendText("}" & vbCrLf)
End If
End With
Catch ex As Exception
Dim oErrorHandler As New sjmErrorHandler(ex)
End Try
End Sub
Private Sub insertSummary(oTextbox As RichTextBox, sDescription As String)
If (sDescription.Length > 0) Then
With oTextbox
.AppendText("/// <summary> " & vbCrLf)
.AppendText("/// " + sDescription & vbCrLf)
.AppendText("/// </summary>" & vbCrLf)
End With
End If
End Sub
Private Function parentSupertype() As String
Dim sParentName = "ZClass"
Dim oParentClass As EA.Element
Dim oTokens As String() = Split(_oEAElement.GetRelationSet(EA.EnumRelationSetType.rsParents), ",")
If oTokens(0).Length > 0 Then
oParentClass = _oDomain.ClassByID.Item(oTokens(0))
sParentName = oParentClass.Name
End If
Return sParentName
End Function
Public Sub AddClassOperations(ByVal bDomainLevel As Boolean)
Dim oMethod As EA.Method
Dim oParameter As EA.Parameter
Dim sLeadingComma As String = ""
Dim oRequiredParameters As Collection
Dim sBehavior As String = ""
With _oSourceOutput
For Each oMethod In _oEAElement.Methods
If (Not bDomainLevel And (Not MethodIncludesStereotype(oMethod, "domain") Or (Not MethodIncludesStereotype(oMethod, "external")) Or _
(bDomainLevel And (MethodIncludesStereotype(oMethod, "domain") Or MethodIncludesStereotype(oMethod, "external"))))) Then
If oMethod.ReturnType.Trim().Length = 0 Then
oMethod.ReturnType = "void"
Else
oMethod.ReturnType = CanonicalType(oMethod.ReturnType)
End If
oMethod.Name = Canonical.CanonicalName(oMethod.Name)
sLeadingComma = ""
.AppendText(vbCrLf)
If oMethod.Notes.Length > 0 Then
For Each sLine As String In Split(oMethod.Notes, vbCrLf)
If sLine.Length > 0 Then
.AppendText(" // " & sLine)
End If
Next
.AppendText(vbCrLf)
End If
oRequiredParameters = New Collection
For Each oParameter In oMethod.Parameters
Application.DoEvents()
oParameter.Name = Canonical.CanonicalName(oParameter.Name)
oParameter.Type = CanonicalType(oParameter.Type)
oRequiredParameters.Add(oParameter)
Next
If MethodIncludesStereotype(oMethod, "event") Then
.AppendText(" public delegate void " + oMethod.Name + "Delegate(")
sLeadingComma = ""
For Each oParameter In oRequiredParameters
.AppendText(sLeadingComma & oParameter.Type + " " + oParameter.Name)
sLeadingComma = ", "
Next
.AppendText(");" & vbCrLf)
insertSummary(_oSourceOutput, oMethod.Notes)
.AppendText(" public static event " + oMethod.Name + "Delegate " + oMethod.Name + "Event; //_________________ '" + oMethod.Name & " (delegate)" & vbCrLf)
insertSummary(_oSourceOutput, oMethod.Notes)
.AppendText(" public static void Raise_" + oMethod.Name + "(")
sLeadingComma = ""
For Each oParameter In oRequiredParameters
.AppendText(sLeadingComma & oParameter.Type + " " + oParameter.Name)
sLeadingComma = ", "
Next
.AppendText(") " & vbCrLf)
.AppendText(" { " & vbCrLf)
.AppendText(" if (null != " + oMethod.Name + "Event) " & vbCrLf)
.AppendText(" { " & vbCrLf)