lutaml 0.9.42 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (583) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +63 -0
  3. data/.github/workflows/links.yml +99 -0
  4. data/.github/workflows/rake.yml +13 -2
  5. data/.github/workflows/release.yml +12 -6
  6. data/.gitignore +3 -0
  7. data/.rubocop.yml +11 -3
  8. data/.rubocop_todo.yml +336 -0
  9. data/Gemfile +18 -7
  10. data/README.adoc +1854 -21
  11. data/Rakefile +7 -1
  12. data/bin/plantuml2lutaml +3 -3
  13. data/bin/yaml2lutaml +2 -2
  14. data/config/diagram_styles.yml +200 -0
  15. data/config/model_transformations.yml +266 -0
  16. data/config/package_metadata.example.yml +58 -0
  17. data/config/qea_schema.yml +1024 -0
  18. data/config/static_site.yml +166 -0
  19. data/docs/.github/workflows/docs.yml +66 -0
  20. data/docs/.github/workflows/links.yml +78 -0
  21. data/docs/CONTINUATION_PLAN.md +168 -0
  22. data/docs/Gemfile +13 -0
  23. data/docs/MIGRATION_GUIDE.md +202 -0
  24. data/docs/README.md +252 -0
  25. data/docs/REFACTOR_PLAN.md +214 -0
  26. data/docs/_config.yml +144 -0
  27. data/docs/_guides/diagram-generation.adoc +316 -0
  28. data/docs/_guides/index.adoc +135 -0
  29. data/docs/{lutaml-express.adoc → _guides/parsing/express-parsing.adoc} +7 -0
  30. data/docs/_guides/parsing/index.adoc +77 -0
  31. data/docs/{lutaml-xmi.adoc → _guides/parsing/xmi-parsing.adoc} +7 -0
  32. data/docs/_guides/sysml-modeling.adoc +37 -0
  33. data/docs/{lutaml-uml.adoc → _guides/uml-modeling.adoc} +8 -2
  34. data/docs/_pages/concepts/diagram-generation.adoc +337 -0
  35. data/docs/_pages/concepts/lur-format.adoc +711 -0
  36. data/docs/_pages/concepts/qea-parsing.adoc +418 -0
  37. data/docs/_pages/core/architecture.adoc +329 -0
  38. data/docs/_pages/core/installation.adoc +321 -0
  39. data/docs/_pages/core/overview.adoc +197 -0
  40. data/docs/_pages/index.adoc +48 -0
  41. data/docs/_pages/uml-syntax.adoc +995 -0
  42. data/docs/_references/configuration/diagram-styles.adoc +716 -0
  43. data/docs/_references/configuration/index.adoc +52 -0
  44. data/docs/_references/configuration/package-metadata.adoc +416 -0
  45. data/docs/_references/formats/index.adoc +42 -0
  46. data/docs/{lutaml_syntax.adoc → _references/formats/lutaml-syntax.adoc} +7 -0
  47. data/docs/_references/formats/qea-structure.adoc +1364 -0
  48. data/docs/_references/index.adoc +197 -0
  49. data/docs/_tutorials/index.adoc +109 -0
  50. data/docs/index.adoc +64 -0
  51. data/docs/lychee.toml +83 -0
  52. data/examples/UML_EA.DTD +6856 -0
  53. data/examples/lur/20251010_current_plateau_v5.1.lur +0 -0
  54. data/examples/lur/basic.lur +0 -0
  55. data/examples/lur/test-output.lur +0 -0
  56. data/examples/lur/test.lur +0 -0
  57. data/examples/lur_basic_usage.rb +220 -0
  58. data/examples/lur_cli_workflow.rb +262 -0
  59. data/examples/lur_statistics.rb +325 -0
  60. data/examples/qea/20251010_current_plateau_v5.1.qea +0 -0
  61. data/examples/qea/ArcGISWorkspace_template.qea +0 -0
  62. data/examples/qea/README_qea_parser.adoc +230 -0
  63. data/examples/qea/UmlModel_template.qea +0 -0
  64. data/examples/qea/basic.qea +0 -0
  65. data/examples/qea/simple.qea +0 -0
  66. data/examples/qea/simple_example.qea +0 -0
  67. data/examples/qea/test.qea +0 -0
  68. data/examples/xmi/20251010_current_plateau_v5.1.xmi +118121 -0
  69. data/examples/xmi/ArcGISWorkspace_template.xmi +1467 -0
  70. data/examples/xmi/Images/EAID_0016F797_D055_4717_AF1A_606413D0A166.svg +158 -0
  71. data/examples/xmi/Images/EAID_00C5C772_5A03_434f_BF30_AC37542A1AAC.svg +659 -0
  72. data/examples/xmi/Images/EAID_0114FD24_9E58_4664_98CD_71305B59AD11.svg +411 -0
  73. data/examples/xmi/Images/EAID_01661E1B_31B6_4167_BCCF_A00678FB4EA2.svg +102 -0
  74. data/examples/xmi/Images/EAID_039FE004_5408_4fc0_89AA_EB319E4F61C7.svg +169 -0
  75. data/examples/xmi/Images/EAID_04EE9625_17A0_4721_BC71_21756DB21D06.svg +403 -0
  76. data/examples/xmi/Images/EAID_05FF9417_1619_4170_B0C9_55AA6B988EF1.svg +175 -0
  77. data/examples/xmi/Images/EAID_09853FB2_AF8A_432f_94C5_6C47461BD937.svg +360 -0
  78. data/examples/xmi/Images/EAID_09927B7F_A657_4819_99E5_AC9DC99227D9.svg +195 -0
  79. data/examples/xmi/Images/EAID_09AF6B8A_557C_43bc_BBB0_47C1E9401EF3.svg +218 -0
  80. data/examples/xmi/Images/EAID_0BE81AC5_031B_4973_A9A0_223CCD92BAA1.svg +471 -0
  81. data/examples/xmi/Images/EAID_0EDEA6EF_4DC8_4979_BB80_28B1B9EBD1D4.svg +56 -0
  82. data/examples/xmi/Images/EAID_0F413534_6AD2_48bc_B4AF_8699D530D91D.svg +262 -0
  83. data/examples/xmi/Images/EAID_1321F39B_AD67_47b5_B5C3_3A42BBFCBDF9.svg +286 -0
  84. data/examples/xmi/Images/EAID_13E09C71_99E7_40b4_B72D_48AF6379BC2E.svg +164 -0
  85. data/examples/xmi/Images/EAID_144955D8_CB4E_4b59_BB0C_E549F7F84943.svg +66 -0
  86. data/examples/xmi/Images/EAID_14E9F5FD_F6CD_4f48_B1CD_F5A40C6D8E83.svg +95 -0
  87. data/examples/xmi/Images/EAID_157826AA_96A7_4278_89A6_94BD0F31409A.svg +63 -0
  88. data/examples/xmi/Images/EAID_159E9DA0_7A54_4817_B72A_401C750F675D.svg +306 -0
  89. data/examples/xmi/Images/EAID_17BC8309_8051_492b_BE87_61CCFE83DB16.svg +45 -0
  90. data/examples/xmi/Images/EAID_1A10EB6D_E2E5_42a6_A31E_B293D93FD07E.svg +193 -0
  91. data/examples/xmi/Images/EAID_1A290AFD_CE96_46a2_8351_A986D77CC727.svg +444 -0
  92. data/examples/xmi/Images/EAID_1B2D9309_C66B_492a_995C_95B2B02E0D7C.svg +168 -0
  93. data/examples/xmi/Images/EAID_1DE6B973_CE8A_416f_909B_54CEA1E5944E.svg +10 -0
  94. data/examples/xmi/Images/EAID_204F4ACC_2230_4c8d_9861_EF5A6844B712.svg +60 -0
  95. data/examples/xmi/Images/EAID_227300E2_4F4B_4955_83B9_FA626CE8680B.svg +188 -0
  96. data/examples/xmi/Images/EAID_22C24D4C_4894_480a_B113_0CB034CB59E9.svg +426 -0
  97. data/examples/xmi/Images/EAID_234BC4F5_8100_4969_BDCB_A24E0E641F23.svg +169 -0
  98. data/examples/xmi/Images/EAID_24446BFC_9FEB_4935_8970_65A4C562A93F.svg +277 -0
  99. data/examples/xmi/Images/EAID_24E8A45C_C99F_49b7_860A_9CF65FF76C76.svg +575 -0
  100. data/examples/xmi/Images/EAID_272F3181_4300_48b7_98A0_A8CFD12B1A72.svg +255 -0
  101. data/examples/xmi/Images/EAID_292E0D94_392C_4da6_A0B5_841501FAE50A.svg +183 -0
  102. data/examples/xmi/Images/EAID_29DD0967_ADAB_4abb_99C5_544821F5E7DA.svg +10 -0
  103. data/examples/xmi/Images/EAID_2A339928_E5EF_4ed2_9E5D_CC2CA5CF248B.svg +310 -0
  104. data/examples/xmi/Images/EAID_2A5E0832_06BE_4381_85D4_9B00E4F95575.svg +155 -0
  105. data/examples/xmi/Images/EAID_2AAB709F_EFCE_496f_8AFE_92809D66A0A9.svg +81 -0
  106. data/examples/xmi/Images/EAID_2C8DD882_8DEA_4065_89F8_DDA796AA0C85.svg +520 -0
  107. data/examples/xmi/Images/EAID_2E98EA19_37D8_4b70_BDCE_CFEE4FA800B0.svg +173 -0
  108. data/examples/xmi/Images/EAID_30D62231_110F_44e8_9C06_6FCDCBA53A09.svg +722 -0
  109. data/examples/xmi/Images/EAID_3206D3FD_1FC4_41c7_8D00_36DB908E9319.svg +181 -0
  110. data/examples/xmi/Images/EAID_3452CC53_9ACB_44eb_9C9D_B90CF862F284.svg +92 -0
  111. data/examples/xmi/Images/EAID_348EE46E_ABD9_40b0_82A1_0285E75BDC52.svg +187 -0
  112. data/examples/xmi/Images/EAID_34FF671B_CFDC_47ad_91DF_ECA6D8358180.svg +217 -0
  113. data/examples/xmi/Images/EAID_359DD694_0100_4bdf_AD5F_712D97E9C69B.svg +157 -0
  114. data/examples/xmi/Images/EAID_35DE714C_49A8_490e_913A_56F39EF317F9.svg +180 -0
  115. data/examples/xmi/Images/EAID_360C79F1_8EDF_41db_A069_DECDC55625BC.svg +31 -0
  116. data/examples/xmi/Images/EAID_36913C58_FF35_4ba2_A04B_9A4824E24609.svg +166 -0
  117. data/examples/xmi/Images/EAID_372F7F7B_57ED_469a_A640_70DB578B3C56.svg +361 -0
  118. data/examples/xmi/Images/EAID_37AC19B9_8433_4fee_A326_763170D54D06.svg +32 -0
  119. data/examples/xmi/Images/EAID_38170608_32B5_4a6f_A68D_A0D7C0C9D019.svg +234 -0
  120. data/examples/xmi/Images/EAID_3A77A5D0_4E1B_4116_8AAD_407FC422B47F.svg +183 -0
  121. data/examples/xmi/Images/EAID_3B8BD087_1683_46b1_8D0D_6F839C46C578.svg +42 -0
  122. data/examples/xmi/Images/EAID_3DC20801_AE8B_4e76_B08C_F574E8A90E13.svg +192 -0
  123. data/examples/xmi/Images/EAID_3DE28C70_C6D4_406c_B49F_EEF52148C8C1.svg +124 -0
  124. data/examples/xmi/Images/EAID_458E093C_BA2B_4292_BEC4_37511C163DDC.svg +140 -0
  125. data/examples/xmi/Images/EAID_45F9B1F7_E568_47c9_B229_953BC2E707E4.svg +266 -0
  126. data/examples/xmi/Images/EAID_46B3041A_8C23_46e6_8E14_ADE7012274C5.svg +80 -0
  127. data/examples/xmi/Images/EAID_47E4600F_CEC9_4245_9BF5_EE38007A9DDB.svg +584 -0
  128. data/examples/xmi/Images/EAID_4881CEEE_792C_4cb0_BEA7_54333B643D0A.svg +155 -0
  129. data/examples/xmi/Images/EAID_48D364F0_DCA4_41e8_B4D4_509B3023B969.svg +17 -0
  130. data/examples/xmi/Images/EAID_4DBDAB9E_4C1C_4cb1_A767_06BD743A50A7.svg +78 -0
  131. data/examples/xmi/Images/EAID_4EB75007_B31D_4f2c_8855_7E9D3A3B17F4.svg +454 -0
  132. data/examples/xmi/Images/EAID_4F421236_FCF3_4aae_B22A_C7E6A5EFBAC7.svg +81 -0
  133. data/examples/xmi/Images/EAID_4FC1D352_2102_4b73_BCB0_1410B29C6BD7.svg +379 -0
  134. data/examples/xmi/Images/EAID_4FE346EA_01E1_4b30_8BE6_BB32EA191E47.svg +126 -0
  135. data/examples/xmi/Images/EAID_5038EEE3_7DD0_4cca_9829_364E044D37E8.svg +199 -0
  136. data/examples/xmi/Images/EAID_508A37DC_9378_4f5a_BD96_48F4D24E03A5.svg +162 -0
  137. data/examples/xmi/Images/EAID_516DA1A2_F0EC_415c_9664_E4CA54E7F05C.svg +136 -0
  138. data/examples/xmi/Images/EAID_52A1DBD3_D3DA_4b6d_8F96_FC6F39F64242.svg +161 -0
  139. data/examples/xmi/Images/EAID_575E87BA_32E9_4a84_AA4E_0EFDFC5D4C07.svg +71 -0
  140. data/examples/xmi/Images/EAID_57E0F1A0_6C72_47ef_B922_B806F9A875E8.svg +209 -0
  141. data/examples/xmi/Images/EAID_5957C373_3FC1_482f_8F35_D809153A17F5.svg +123 -0
  142. data/examples/xmi/Images/EAID_59A66AE2_412C_48a6_BFC7_EA56CF11D269.svg +218 -0
  143. data/examples/xmi/Images/EAID_5A43833E_680B_4a90_8931_0C902304E029.svg +236 -0
  144. data/examples/xmi/Images/EAID_5D6DB5A0_5047_4bac_9E60_69904A60B56D.svg +353 -0
  145. data/examples/xmi/Images/EAID_5DA1E7A7_8E59_4803_A831_E9F3EC27328F.svg +242 -0
  146. data/examples/xmi/Images/EAID_5E2C1E2A_82A8_47f4_B2ED_1398D72BFCFD.svg +246 -0
  147. data/examples/xmi/Images/EAID_6052620C_4BD5_49f6_A21C_AD7E6DCA2795.svg +290 -0
  148. data/examples/xmi/Images/EAID_6481E2CC_35A6_43b0_88D4_10A667A2BC2D.svg +60 -0
  149. data/examples/xmi/Images/EAID_660C7D03_A26C_4977_A7BA_9D0A773DA811.svg +318 -0
  150. data/examples/xmi/Images/EAID_671F3C3D_35B6_4514_B5B6_DD7E84925493.svg +24 -0
  151. data/examples/xmi/Images/EAID_676B9C9A_D85F_4d2f_A46B_73F02090DC87.svg +127 -0
  152. data/examples/xmi/Images/EAID_6797FEFA_5801_48e4_8B9C_3C824C0E165D.svg +412 -0
  153. data/examples/xmi/Images/EAID_6807F4EE_18EF_4e7e_ACCF_D5BD323AFDE9.svg +130 -0
  154. data/examples/xmi/Images/EAID_69E81E34_CF28_4c7f_A48F_5941BA85CEE3.svg +96 -0
  155. data/examples/xmi/Images/EAID_6A3C55E8_3C3C_4f3a_8AAC_0299C5B23070.svg +10 -0
  156. data/examples/xmi/Images/EAID_6BAC333E_E2C2_42c7_8DDF_6B4FA0FFC03B.svg +143 -0
  157. data/examples/xmi/Images/EAID_6D0349D5_3F1B_4b28_82D2_910743DEB5E5.svg +114 -0
  158. data/examples/xmi/Images/EAID_6E95B74E_8A09_4698_9E9E_23BCFD2CE194.svg +37 -0
  159. data/examples/xmi/Images/EAID_70C77F92_5614_4b22_8C8E_67859F59D8FD.svg +254 -0
  160. data/examples/xmi/Images/EAID_71F9216B_E7A7_4083_B08E_6C71B57F3A1F.svg +187 -0
  161. data/examples/xmi/Images/EAID_73025C5A_08FC_47ff_AB2F_C7F79CF54B41.svg +145 -0
  162. data/examples/xmi/Images/EAID_74C974B6_6D07_425d_B7AC_C8899E3B4967.svg +76 -0
  163. data/examples/xmi/Images/EAID_7504FCD2_524C_4e7d_BAE4_4E58A8A8A12C.svg +196 -0
  164. data/examples/xmi/Images/EAID_78030266_3603_4747_9D75_03D16614BE7D.svg +35 -0
  165. data/examples/xmi/Images/EAID_785226C1_12B1_4104_A4C1_F19B70B9FB71.svg +348 -0
  166. data/examples/xmi/Images/EAID_7854470F_26B8_4d3c_AFDF_C05BCE6ED0CD.svg +72 -0
  167. data/examples/xmi/Images/EAID_794F4A8F_18CA_4e9f_8477_A6F0E5ED22D4.svg +187 -0
  168. data/examples/xmi/Images/EAID_7A24839E_C8AE_424d_B7D2_6DA16DC813E7.svg +114 -0
  169. data/examples/xmi/Images/EAID_7A3649FD_E960_4ae6_B9B1_A9001C066AE7.svg +181 -0
  170. data/examples/xmi/Images/EAID_7B2C6765_AB68_439a_87F3_DAC323CB2AF5.svg +196 -0
  171. data/examples/xmi/Images/EAID_7C44AC09_27C1_47b3_9A85_88EC71C081FF.svg +55 -0
  172. data/examples/xmi/Images/EAID_7CE102CA_97C1_4cac_BD3B_0500D3712D2A.svg +195 -0
  173. data/examples/xmi/Images/EAID_7D960BD8_65D8_4934_9C11_4EF860DD8FBA.svg +90 -0
  174. data/examples/xmi/Images/EAID_80939C98_A456_48c3_BCEA_4B72851F2DF6.svg +174 -0
  175. data/examples/xmi/Images/EAID_812FE862_76ED_44f0_B678_7A4601B395CF.svg +142 -0
  176. data/examples/xmi/Images/EAID_81B76F5B_9D64_4bbf_8AC8_34234FB87533.svg +740 -0
  177. data/examples/xmi/Images/EAID_84352F1A_195B_411b_9552_5BFC40BF90B5.svg +105 -0
  178. data/examples/xmi/Images/EAID_846DD800_139C_4d47_A1DF_3FB1AC5D130F.svg +554 -0
  179. data/examples/xmi/Images/EAID_84A9C65B_FD6D_4bb5_818F_E8C35FF5BCD1.svg +228 -0
  180. data/examples/xmi/Images/EAID_853674F5_7DC9_4aae_809B_5728098B5D5B.svg +154 -0
  181. data/examples/xmi/Images/EAID_860CBBFB_2F27_408f_9144_751F9D1F487F.svg +273 -0
  182. data/examples/xmi/Images/EAID_87476527_7B9B_4b92_967E_3D38365470CA.svg +239 -0
  183. data/examples/xmi/Images/EAID_87DAE930_5069_4c58_AC65_4B0B2C0F32C8.svg +10 -0
  184. data/examples/xmi/Images/EAID_88AF6BD7_BC34_406f_BB59_47CFAB4A7D5D.svg +116 -0
  185. data/examples/xmi/Images/EAID_88D0CB44_20D0_44fc_A6E3_B663332EF401.svg +200 -0
  186. data/examples/xmi/Images/EAID_8BB1CA0C_C003_4678_973B_A1C3308E021D.svg +136 -0
  187. data/examples/xmi/Images/EAID_8DAB169F_D189_4320_A0F5_4443E3297F0E.svg +181 -0
  188. data/examples/xmi/Images/EAID_8FD488EF_BAAB_40ec_A7ED_F7CC831D546E.svg +324 -0
  189. data/examples/xmi/Images/EAID_90BCA409_BB45_42c5_AFA5_45FE3D995904.svg +342 -0
  190. data/examples/xmi/Images/EAID_926AFE38_01FA_469e_B6AA_ED5F4D62B66F.svg +105 -0
  191. data/examples/xmi/Images/EAID_92AB0FD0_B0FB_4ceb_8EAE_66B6600D31D7.svg +681 -0
  192. data/examples/xmi/Images/EAID_92C43670_3057_47f1_A576_C60843FF3D26.svg +136 -0
  193. data/examples/xmi/Images/EAID_93F63576_BE01_4cd8_8A91_C674FF77FC3D.svg +718 -0
  194. data/examples/xmi/Images/EAID_9400D9BC_05A5_41fc_83F7_02E5C67F9718.svg +487 -0
  195. data/examples/xmi/Images/EAID_95246DCF_1C09_4a16_9512_98000F56B3D8.svg +292 -0
  196. data/examples/xmi/Images/EAID_9994BF62_51E2_42cd_BB35_16C537B6718A.svg +715 -0
  197. data/examples/xmi/Images/EAID_9AAD6C21_B1E7_4472_B64A_FB5E3569D970.svg +116 -0
  198. data/examples/xmi/Images/EAID_9BD7189A_877B_4ca9_B42C_817DEF144FB2.svg +284 -0
  199. data/examples/xmi/Images/EAID_9DA6C553_94FC_4204_83AD_ECC4B45A53EF.svg +159 -0
  200. data/examples/xmi/Images/EAID_9EE6A41B_5FAA_4c89_B98F_732059778630.svg +10 -0
  201. data/examples/xmi/Images/EAID_9F1A4B54_46F6_435c_9529_E43E54CF6050.svg +172 -0
  202. data/examples/xmi/Images/EAID_9FE1EA7B_4CEF_4976_A281_93A94315BD84.svg +153 -0
  203. data/examples/xmi/Images/EAID_A0695647_6172_4262_8C30_67441399609C.svg +290 -0
  204. data/examples/xmi/Images/EAID_A081C63E_D6F2_41a7_A99C_307836754AFA.svg +149 -0
  205. data/examples/xmi/Images/EAID_A24E2778_5AD9_44f2_AB8F_5CD3913477D6.svg +194 -0
  206. data/examples/xmi/Images/EAID_A264F089_F9B3_406c_A3A8_FF34903797D3.svg +143 -0
  207. data/examples/xmi/Images/EAID_A282E5D1_2A13_4e7f_BC76_5D086DD4A577.svg +357 -0
  208. data/examples/xmi/Images/EAID_A3BCE1D6_9DB5_4272_A020_4C0E194B99CC.svg +171 -0
  209. data/examples/xmi/Images/EAID_A56E3818_D1B8_4b63_B69E_FBAC4A8AF482.svg +218 -0
  210. data/examples/xmi/Images/EAID_A57215D5_75C5_4532_BCF4_264A77CD62F1.svg +204 -0
  211. data/examples/xmi/Images/EAID_A59065AF_9669_486c_9582_9693177CFC7F.svg +263 -0
  212. data/examples/xmi/Images/EAID_A759374D_589A_488c_99EF_537ACB9B1FF9.svg +398 -0
  213. data/examples/xmi/Images/EAID_A7B25F46_F18A_4373_B16D_8C6AC0B868B0.svg +174 -0
  214. data/examples/xmi/Images/EAID_A9FE9E6F_A5F4_47e5_A6BA_26E22C7346B6.svg +310 -0
  215. data/examples/xmi/Images/EAID_AA62CDEB_55EC_498d_B326_4AA2C9AF6A05.svg +144 -0
  216. data/examples/xmi/Images/EAID_AAF52AF6_F7F9_4005_AE46_8920847BEA03.svg +144 -0
  217. data/examples/xmi/Images/EAID_AB281AC1_7CB8_404a_8124_34343DDD84E2.svg +198 -0
  218. data/examples/xmi/Images/EAID_AB7F1FDF_A66B_42a1_B8A3_7F594BAAD508.svg +143 -0
  219. data/examples/xmi/Images/EAID_AC2191E3_76E3_40b2_9E21_0E0B9B5277D2.svg +114 -0
  220. data/examples/xmi/Images/EAID_AD451676_A7C8_4c6a_A925_A9B9CA344142.svg +339 -0
  221. data/examples/xmi/Images/EAID_ADBA40A1_9375_4c1b_9938_0990612EB615.svg +429 -0
  222. data/examples/xmi/Images/EAID_ADC8773C_1B27_48ac_BAC1_14C1C919FAF6.svg +245 -0
  223. data/examples/xmi/Images/EAID_AE0718DF_AF69_4ea1_A099_E20028FE40A1.svg +173 -0
  224. data/examples/xmi/Images/EAID_B0DDB85D_A00C_4a7f_8C06_CCA15E5E4FE5.svg +31 -0
  225. data/examples/xmi/Images/EAID_B27ED282_D5E5_4f33_8AC1_62802F9E0B35.svg +256 -0
  226. data/examples/xmi/Images/EAID_B3AFECCB_17DD_44d6_8A44_2C38D9A64C0B.svg +95 -0
  227. data/examples/xmi/Images/EAID_B3B6C5B1_278E_4714_8244_B6C28B66AB50.svg +176 -0
  228. data/examples/xmi/Images/EAID_B53E76CD_A0F2_4e2f_B3AB_796D85964EF2.svg +179 -0
  229. data/examples/xmi/Images/EAID_B55D6E67_0BDD_4163_B359_11A6FBA89C74.svg +207 -0
  230. data/examples/xmi/Images/EAID_B58D1A53_E860_41a3_8352_11C274093E83.svg +189 -0
  231. data/examples/xmi/Images/EAID_B62C02B3_69DB_49e9_8089_4EE398BDE666.svg +165 -0
  232. data/examples/xmi/Images/EAID_BC008774_B539_4150_8174_B675989053D0.svg +22 -0
  233. data/examples/xmi/Images/EAID_BC1F7E00_082D_4a26_922B_3967A8D66859.svg +266 -0
  234. data/examples/xmi/Images/EAID_BDA613D8_402A_475a_AA15_683D88FD3D23.svg +183 -0
  235. data/examples/xmi/Images/EAID_C028B286_4C85_47d8_B6D5_80B28F556E82.svg +303 -0
  236. data/examples/xmi/Images/EAID_C173A6F4_1D1B_400e_AD8C_64FFF7CD5BE5.svg +178 -0
  237. data/examples/xmi/Images/EAID_C1834072_CADC_4ce4_B0FC_8284AE5CF4A4.svg +158 -0
  238. data/examples/xmi/Images/EAID_C1EC985B_5CBD_4e91_8661_EB4EF23781D9.svg +286 -0
  239. data/examples/xmi/Images/EAID_C31C1314_B679_4413_B8FE_A2CD584FC128.svg +305 -0
  240. data/examples/xmi/Images/EAID_C37CFBD6_69BA_42fb_9AC7_2D329D931BCF.svg +171 -0
  241. data/examples/xmi/Images/EAID_C857C934_306F_463a_87D5_257CB225ECFE.svg +174 -0
  242. data/examples/xmi/Images/EAID_C96797DE_2238_42d3_896A_9F92500270ED.svg +180 -0
  243. data/examples/xmi/Images/EAID_C96CBC24_B20E_459a_8F9D_75B61CDCB89F.svg +656 -0
  244. data/examples/xmi/Images/EAID_CACB523D_56A5_4f05_B3C2_51BB18F380FD.svg +158 -0
  245. data/examples/xmi/Images/EAID_CB34B578_101B_48b4_9271_214FFEA6A83A.svg +409 -0
  246. data/examples/xmi/Images/EAID_CBBD6CF4_0A1E_4406_9930_89DE43527910.svg +361 -0
  247. data/examples/xmi/Images/EAID_CC06A828_3750_472f_8DB2_C2E0863FCE17.svg +96 -0
  248. data/examples/xmi/Images/EAID_CD5CF053_1772_4a0f_962D_B17054D8EEAA.svg +173 -0
  249. data/examples/xmi/Images/EAID_CE440B5A_9534_4c75_9BA5_50862BB396C2.svg +97 -0
  250. data/examples/xmi/Images/EAID_CE4734FC_7986_4b3a_807F_A5B2C7EDE9E4.svg +193 -0
  251. data/examples/xmi/Images/EAID_D14AA320_9D41_4366_8739_9C2C21F96AE1.svg +32 -0
  252. data/examples/xmi/Images/EAID_D2FA55D3_C733_4a4d_92D0_0BC7AC0BB5BC.svg +108 -0
  253. data/examples/xmi/Images/EAID_D351FC34_FB03_488d_ADA4_BDB93DA9CB02.svg +49 -0
  254. data/examples/xmi/Images/EAID_D368FDF3_BDC5_4718_A701_351C8587A376.svg +592 -0
  255. data/examples/xmi/Images/EAID_D4DA8C48_3998_450d_87C4_9D65C9FECDB4.svg +42 -0
  256. data/examples/xmi/Images/EAID_D5464ECF_290E_4b2b_A6C4_25BE80F886CB.svg +76 -0
  257. data/examples/xmi/Images/EAID_D55235B0_61E9_461a_8379_2B8BF2403BE2.svg +147 -0
  258. data/examples/xmi/Images/EAID_D555ED73_F010_45d7_8A53_45A33C64C249.svg +318 -0
  259. data/examples/xmi/Images/EAID_D7AAC526_267E_45a0_A853_3207F02363F8.svg +45 -0
  260. data/examples/xmi/Images/EAID_D998B20D_A875_4ef8_A9CE_996BE56602BD.svg +158 -0
  261. data/examples/xmi/Images/EAID_DBFA8B39_F5B7_4c0e_9552_19AEAE5BA64E.svg +200 -0
  262. data/examples/xmi/Images/EAID_DE47A47D_E7BE_4e6f_BA81_F789EE8CFE72.svg +61 -0
  263. data/examples/xmi/Images/EAID_DFBB1072_8EC5_4384_8241_7EDF4B6B888B.svg +78 -0
  264. data/examples/xmi/Images/EAID_E325B9D8_E955_4aed_8125_63167BD40320.svg +67 -0
  265. data/examples/xmi/Images/EAID_E32D9D02_CAE9_4a47_92A8_3290EDCD6E6D.svg +79 -0
  266. data/examples/xmi/Images/EAID_E3B28611_7857_458a_B0BC_736E777B88EC.svg +194 -0
  267. data/examples/xmi/Images/EAID_E43C37EC_1176_4d2e_8B98_B6F3DFF6A092.svg +96 -0
  268. data/examples/xmi/Images/EAID_E591C1CF_7F35_4160_8A72_DFA097AD5811.svg +271 -0
  269. data/examples/xmi/Images/EAID_E77C66A2_2E94_4196_BFC6_662FE5AEEB6F.svg +332 -0
  270. data/examples/xmi/Images/EAID_E7AABA98_2450_4986_9736_DCCAF0108C50.svg +639 -0
  271. data/examples/xmi/Images/EAID_E7D9A2C4_72D6_40b9_8EB8_6B35476246B3.svg +134 -0
  272. data/examples/xmi/Images/EAID_E9CDAD85_ECF1_43de_819F_30A0D01785E6.svg +193 -0
  273. data/examples/xmi/Images/EAID_EC8AF507_F441_4e8a_B8A7_C1690F3C7D0B.svg +58 -0
  274. data/examples/xmi/Images/EAID_ED501058_D540_47ac_8EBC_5921E8C0BF57.svg +384 -0
  275. data/examples/xmi/Images/EAID_EFBF5F0F_DF74_4944_8791_114F5637C335.svg +590 -0
  276. data/examples/xmi/Images/EAID_EFFFA027_2A1F_425c_8437_BF89AADC8893.svg +365 -0
  277. data/examples/xmi/Images/EAID_F07E7718_B2C2_4a65_B5DD_477CB73E971E.svg +165 -0
  278. data/examples/xmi/Images/EAID_F0F20BDF_C729_47f7_B6FC_25ED2C4609CA.svg +61 -0
  279. data/examples/xmi/Images/EAID_F32E5AFE_8605_4c77_AE69_D0D0A6E380AC.svg +76 -0
  280. data/examples/xmi/Images/EAID_F3F00F45_CD37_46fd_B521_D1040EB2FB16.svg +123 -0
  281. data/examples/xmi/Images/EAID_F46E8F19_D8F1_4a3d_B87B_B0BAB4F50F50.svg +202 -0
  282. data/examples/xmi/Images/EAID_F48E5F6E_2411_4635_9315_3EAA4CFA29F7.svg +351 -0
  283. data/examples/xmi/Images/EAID_F4C23F9E_DD74_4fed_B75D_AD3C6448BA24.svg +189 -0
  284. data/examples/xmi/Images/EAID_F853B3C4_B145_4ef0_B261_C3CC0475B6D2.svg +215 -0
  285. data/examples/xmi/Images/EAID_F8BE68CA_1F8F_47e5_9454_01A2EB7D388A.svg +124 -0
  286. data/examples/xmi/Images/EAID_F92A6A28_612E_468e_9E39_D7AE7D24E24D.svg +208 -0
  287. data/examples/xmi/Images/EAID_F995FA49_B86E_4c94_BE5E_C928FB6B87D0.svg +302 -0
  288. data/examples/xmi/Images/EAID_FEAE013A_A4E4_4283_A491_1FEB8D0EBA28.svg +524 -0
  289. data/examples/xmi/Images/EAID_FEBE5726_3751_470b_9023_8C569202E97E.svg +730 -0
  290. data/examples/xmi/UML_EA.DTD +6856 -0
  291. data/examples/xmi/UmlModel_template.xmi +23 -0
  292. data/examples/xmi/basic.xmi +9086 -0
  293. data/examples/xmi/simple.xmi +655 -0
  294. data/examples/xmi/simple_example.xmi +23 -0
  295. data/examples/xmi/test.xmi +1703 -0
  296. data/exe/lutaml +2 -16
  297. data/exe/lutaml-wsd2uml +3 -3
  298. data/exe/lutaml-yaml2uml +2 -2
  299. data/lib/lutaml/cli/commands/base_command.rb +118 -0
  300. data/lib/lutaml/cli/element_identifier.rb +165 -0
  301. data/lib/lutaml/cli/enhanced_formatter.rb +502 -0
  302. data/lib/lutaml/cli/interactive_shell.rb +911 -0
  303. data/lib/lutaml/cli/lml_commands.rb +201 -0
  304. data/lib/lutaml/cli/output_formatter.rb +348 -0
  305. data/lib/lutaml/cli/resource_registry.rb +127 -0
  306. data/lib/lutaml/cli/tree_view_formatter.rb +308 -0
  307. data/lib/lutaml/cli/uml/build_command.rb +538 -0
  308. data/lib/lutaml/cli/uml/diagram_command.rb +421 -0
  309. data/lib/lutaml/cli/uml/export_command.rb +78 -0
  310. data/lib/lutaml/cli/uml/find_command.rb +122 -0
  311. data/lib/lutaml/cli/uml/info_command.rb +104 -0
  312. data/lib/lutaml/cli/uml/inspect_command.rb +88 -0
  313. data/lib/lutaml/cli/uml/ls_command.rb +105 -0
  314. data/lib/lutaml/cli/uml/repl_command.rb +50 -0
  315. data/lib/lutaml/cli/uml/search_command.rb +88 -0
  316. data/lib/lutaml/cli/uml/serve_command.rb +59 -0
  317. data/lib/lutaml/cli/uml/shared_helpers.rb +51 -0
  318. data/lib/lutaml/cli/uml/spa_command.rb +209 -0
  319. data/lib/lutaml/cli/uml/stats_command.rb +60 -0
  320. data/lib/lutaml/cli/uml/tree_command.rb +85 -0
  321. data/lib/lutaml/cli/uml/validate_command.rb +195 -0
  322. data/lib/lutaml/cli/uml/verify_command.rb +107 -0
  323. data/lib/lutaml/cli/uml_commands.rb +163 -0
  324. data/lib/lutaml/cli.rb +72 -0
  325. data/lib/lutaml/command_line.rb +8 -6
  326. data/lib/lutaml/converter/dsl_to_uml.rb +2 -0
  327. data/lib/lutaml/converter/xmi_to_uml.rb +43 -22
  328. data/lib/lutaml/ea/diagram/configuration.rb +379 -0
  329. data/lib/lutaml/ea/diagram/element_renderers/base_renderer.rb +81 -0
  330. data/lib/lutaml/ea/diagram/element_renderers/class_renderer.rb +330 -0
  331. data/lib/lutaml/ea/diagram/element_renderers/connector_renderer.rb +55 -0
  332. data/lib/lutaml/ea/diagram/element_renderers/package_renderer.rb +69 -0
  333. data/lib/lutaml/ea/diagram/extractor.rb +559 -0
  334. data/lib/lutaml/ea/diagram/layout_engine.rb +251 -0
  335. data/lib/lutaml/ea/diagram/path_builder.rb +258 -0
  336. data/lib/lutaml/ea/diagram/style_parser.rb +315 -0
  337. data/lib/lutaml/ea/diagram/style_resolver.rb +291 -0
  338. data/lib/lutaml/ea/diagram/svg_renderer.rb +285 -0
  339. data/lib/lutaml/ea/diagram/util.rb +69 -0
  340. data/lib/lutaml/ea/diagram.rb +77 -0
  341. data/lib/lutaml/express/parsers/exp.rb +1 -1
  342. data/lib/lutaml/express.rb +4 -2
  343. data/lib/lutaml/formatter/base.rb +6 -6
  344. data/lib/lutaml/formatter/graphviz.rb +10 -8
  345. data/lib/lutaml/formatter.rb +3 -0
  346. data/lib/lutaml/layout/engine.rb +9 -7
  347. data/lib/lutaml/layout/graph_viz_engine.rb +2 -1
  348. data/lib/lutaml/layout.rb +8 -0
  349. data/lib/lutaml/model_transformations/configuration.rb +333 -0
  350. data/lib/lutaml/model_transformations/format_registry.rb +394 -0
  351. data/lib/lutaml/model_transformations/parsers/base_parser.rb +389 -0
  352. data/lib/lutaml/model_transformations/parsers/qea_parser.rb +455 -0
  353. data/lib/lutaml/model_transformations/parsers/xmi_parser.rb +301 -0
  354. data/lib/lutaml/model_transformations/transformation_engine.rb +409 -0
  355. data/lib/lutaml/model_transformations.rb +143 -0
  356. data/lib/lutaml/parser.rb +15 -7
  357. data/lib/lutaml/qea/benchmark.rb +212 -0
  358. data/lib/lutaml/qea/database.rb +324 -0
  359. data/lib/lutaml/qea/factory/association_transformer.rb +115 -0
  360. data/lib/lutaml/qea/factory/attribute_tag_transformer.rb +60 -0
  361. data/lib/lutaml/qea/factory/attribute_transformer.rb +103 -0
  362. data/lib/lutaml/qea/factory/base_transformer.rb +132 -0
  363. data/lib/lutaml/qea/factory/class_transformer.rb +734 -0
  364. data/lib/lutaml/qea/factory/constraint_transformer.rb +78 -0
  365. data/lib/lutaml/qea/factory/data_type_transformer.rb +162 -0
  366. data/lib/lutaml/qea/factory/diagram_transformer.rb +182 -0
  367. data/lib/lutaml/qea/factory/document_builder.rb +275 -0
  368. data/lib/lutaml/qea/factory/ea_to_uml_factory.rb +260 -0
  369. data/lib/lutaml/qea/factory/enum_transformer.rb +87 -0
  370. data/lib/lutaml/qea/factory/generalization_transformer.rb +106 -0
  371. data/lib/lutaml/qea/factory/instance_transformer.rb +96 -0
  372. data/lib/lutaml/qea/factory/object_property_transformer.rb +61 -0
  373. data/lib/lutaml/qea/factory/operation_transformer.rb +75 -0
  374. data/lib/lutaml/qea/factory/package_transformer.rb +199 -0
  375. data/lib/lutaml/qea/factory/reference_resolver.rb +99 -0
  376. data/lib/lutaml/qea/factory/tagged_value_transformer.rb +41 -0
  377. data/lib/lutaml/qea/factory/transformer_registry.rb +85 -0
  378. data/lib/lutaml/qea/file_detector.rb +178 -0
  379. data/lib/lutaml/qea/infrastructure/database_connection.rb +100 -0
  380. data/lib/lutaml/qea/infrastructure/schema_reader.rb +136 -0
  381. data/lib/lutaml/qea/infrastructure/table_reader.rb +224 -0
  382. data/lib/lutaml/qea/models/base_model.rb +48 -0
  383. data/lib/lutaml/qea/models/ea_attribute.rb +135 -0
  384. data/lib/lutaml/qea/models/ea_attribute_tag.rb +109 -0
  385. data/lib/lutaml/qea/models/ea_complexity_type.rb +81 -0
  386. data/lib/lutaml/qea/models/ea_connector.rb +162 -0
  387. data/lib/lutaml/qea/models/ea_connector_type.rb +62 -0
  388. data/lib/lutaml/qea/models/ea_constraint_type.rb +65 -0
  389. data/lib/lutaml/qea/models/ea_datatype.rb +108 -0
  390. data/lib/lutaml/qea/models/ea_diagram.rb +117 -0
  391. data/lib/lutaml/qea/models/ea_diagram_link.rb +80 -0
  392. data/lib/lutaml/qea/models/ea_diagram_object.rb +86 -0
  393. data/lib/lutaml/qea/models/ea_diagram_type.rb +58 -0
  394. data/lib/lutaml/qea/models/ea_document.rb +68 -0
  395. data/lib/lutaml/qea/models/ea_object.rb +208 -0
  396. data/lib/lutaml/qea/models/ea_object_constraint.rb +62 -0
  397. data/lib/lutaml/qea/models/ea_object_property.rb +96 -0
  398. data/lib/lutaml/qea/models/ea_object_type.rb +75 -0
  399. data/lib/lutaml/qea/models/ea_operation.rb +153 -0
  400. data/lib/lutaml/qea/models/ea_operation_param.rb +73 -0
  401. data/lib/lutaml/qea/models/ea_package.rb +75 -0
  402. data/lib/lutaml/qea/models/ea_script.rb +69 -0
  403. data/lib/lutaml/qea/models/ea_status_type.rb +68 -0
  404. data/lib/lutaml/qea/models/ea_stereotype.rb +59 -0
  405. data/lib/lutaml/qea/models/ea_tagged_value.rb +105 -0
  406. data/lib/lutaml/qea/models/ea_xref.rb +174 -0
  407. data/lib/lutaml/qea/parser.rb +61 -0
  408. data/lib/lutaml/qea/repositories/base_repository.rb +215 -0
  409. data/lib/lutaml/qea/repositories/object_repository.rb +221 -0
  410. data/lib/lutaml/qea/services/configuration.rb +211 -0
  411. data/lib/lutaml/qea/services/database_loader.rb +215 -0
  412. data/lib/lutaml/qea/validation/association_validator.rb +75 -0
  413. data/lib/lutaml/qea/validation/attribute_validator.rb +103 -0
  414. data/lib/lutaml/qea/validation/base_validator.rb +305 -0
  415. data/lib/lutaml/qea/validation/class_validator.rb +123 -0
  416. data/lib/lutaml/qea/validation/database/circular_reference_validator.rb +111 -0
  417. data/lib/lutaml/qea/validation/database/orphan_validator.rb +155 -0
  418. data/lib/lutaml/qea/validation/database/referential_integrity_validator.rb +130 -0
  419. data/lib/lutaml/qea/validation/diagram_validator.rb +114 -0
  420. data/lib/lutaml/qea/validation/formatters/json_formatter.rb +137 -0
  421. data/lib/lutaml/qea/validation/formatters/text_formatter.rb +235 -0
  422. data/lib/lutaml/qea/validation/operation_validator.rb +81 -0
  423. data/lib/lutaml/qea/validation/package_validator.rb +113 -0
  424. data/lib/lutaml/qea/validation/validation_engine.rb +497 -0
  425. data/lib/lutaml/qea/validation/validation_message.rb +144 -0
  426. data/lib/lutaml/qea/validation/validation_result.rb +212 -0
  427. data/lib/lutaml/qea/validation/validator_registry.rb +134 -0
  428. data/lib/lutaml/qea/verification/comparison_result.rb +264 -0
  429. data/lib/lutaml/qea/verification/document_normalizer.rb +177 -0
  430. data/lib/lutaml/qea/verification/document_verifier.rb +320 -0
  431. data/lib/lutaml/qea/verification/element_comparator.rb +306 -0
  432. data/lib/lutaml/qea/verification/structure_matcher.rb +287 -0
  433. data/lib/lutaml/qea.rb +226 -0
  434. data/lib/lutaml/sysml/allocate.rb +2 -0
  435. data/lib/lutaml/sysml/allocated.rb +2 -0
  436. data/lib/lutaml/sysml/binding_connector.rb +2 -0
  437. data/lib/lutaml/sysml/block.rb +2 -0
  438. data/lib/lutaml/sysml/constraint_block.rb +2 -0
  439. data/lib/lutaml/sysml/copy.rb +2 -0
  440. data/lib/lutaml/sysml/derive_requirement.rb +2 -0
  441. data/lib/lutaml/sysml/nested_connector_end.rb +2 -0
  442. data/lib/lutaml/sysml/refine.rb +2 -0
  443. data/lib/lutaml/sysml/requirement.rb +2 -0
  444. data/lib/lutaml/sysml/requirement_related.rb +2 -0
  445. data/lib/lutaml/sysml/satisfy.rb +2 -0
  446. data/lib/lutaml/sysml/test_case.rb +2 -0
  447. data/lib/lutaml/sysml/trace.rb +2 -0
  448. data/lib/lutaml/sysml/verify.rb +2 -0
  449. data/lib/lutaml/sysml/xmi_file.rb +2 -0
  450. data/lib/lutaml/sysml.rb +3 -1
  451. data/lib/lutaml/uml/association.rb +4 -0
  452. data/lib/lutaml/uml/class.rb +11 -9
  453. data/lib/lutaml/uml/classifier.rb +3 -0
  454. data/lib/lutaml/uml/comment.rb +13 -0
  455. data/lib/lutaml/uml/data_type.rb +7 -6
  456. data/lib/lutaml/uml/diagram.rb +12 -0
  457. data/lib/lutaml/uml/diagram_link.rb +26 -0
  458. data/lib/lutaml/uml/diagram_object.rb +30 -0
  459. data/lib/lutaml/uml/document.rb +18 -0
  460. data/lib/lutaml/uml/enum.rb +4 -3
  461. data/lib/lutaml/uml/fontname.rb +13 -0
  462. data/lib/lutaml/uml/generalization.rb +2 -0
  463. data/lib/lutaml/uml/group.rb +2 -0
  464. data/lib/lutaml/uml/namespace.rb +2 -2
  465. data/lib/lutaml/uml/node/{field.rb → attribute.rb} +4 -4
  466. data/lib/lutaml/uml/node/base.rb +1 -1
  467. data/lib/lutaml/uml/node/class_node.rb +12 -12
  468. data/lib/lutaml/uml/node/class_relationship.rb +2 -2
  469. data/lib/lutaml/uml/node/document.rb +2 -2
  470. data/lib/lutaml/uml/node/method_argument.rb +3 -3
  471. data/lib/lutaml/uml/node/{method.rb → operation.rb} +4 -4
  472. data/lib/lutaml/uml/node/relationship.rb +3 -3
  473. data/lib/lutaml/uml/package.rb +7 -4
  474. data/lib/lutaml/uml/package_path.rb +235 -0
  475. data/lib/lutaml/uml/parsers/attribute.rb +2 -2
  476. data/lib/lutaml/uml/parsers/dsl.rb +3 -4
  477. data/lib/lutaml/uml/parsers/yaml.rb +1 -1
  478. data/lib/lutaml/uml/qualified_name.rb +178 -0
  479. data/lib/lutaml/uml/tagged_value.rb +21 -0
  480. data/lib/lutaml/uml/top_element.rb +7 -1
  481. data/lib/lutaml/uml/top_element_attribute.rb +4 -0
  482. data/lib/lutaml/uml/validation/document_structure_validator.rb +389 -0
  483. data/lib/lutaml/uml.rb +89 -45
  484. data/lib/lutaml/uml_repository/error_handler.rb +203 -0
  485. data/lib/lutaml/uml_repository/exporters/base_exporter.rb +61 -0
  486. data/lib/lutaml/uml_repository/exporters/json_exporter.rb +344 -0
  487. data/lib/lutaml/uml_repository/exporters/markdown_exporter.rb +598 -0
  488. data/lib/lutaml/uml_repository/index_builder.rb +460 -0
  489. data/lib/lutaml/uml_repository/lazy_repository.rb +238 -0
  490. data/lib/lutaml/uml_repository/package_exporter.rb +336 -0
  491. data/lib/lutaml/uml_repository/package_loader.rb +220 -0
  492. data/lib/lutaml/uml_repository/package_metadata.rb +77 -0
  493. data/lib/lutaml/uml_repository/presenters/association_presenter.rb +86 -0
  494. data/lib/lutaml/uml_repository/presenters/attribute_presenter.rb +101 -0
  495. data/lib/lutaml/uml_repository/presenters/class_presenter.rb +75 -0
  496. data/lib/lutaml/uml_repository/presenters/datatype_presenter.rb +108 -0
  497. data/lib/lutaml/uml_repository/presenters/diagram_presenter.rb +508 -0
  498. data/lib/lutaml/uml_repository/presenters/element_presenter.rb +92 -0
  499. data/lib/lutaml/uml_repository/presenters/enum_presenter.rb +83 -0
  500. data/lib/lutaml/uml_repository/presenters/package_presenter.rb +48 -0
  501. data/lib/lutaml/uml_repository/presenters/presenter_factory.rb +76 -0
  502. data/lib/lutaml/uml_repository/queries/association_query.rb +187 -0
  503. data/lib/lutaml/uml_repository/queries/base_query.rb +45 -0
  504. data/lib/lutaml/uml_repository/queries/class_query.rb +117 -0
  505. data/lib/lutaml/uml_repository/queries/diagram_query.rb +111 -0
  506. data/lib/lutaml/uml_repository/queries/inheritance_query.rb +259 -0
  507. data/lib/lutaml/uml_repository/queries/package_query.rb +239 -0
  508. data/lib/lutaml/uml_repository/queries/search_query.rb +357 -0
  509. data/lib/lutaml/uml_repository/query_dsl/conditions/base_condition.rb +28 -0
  510. data/lib/lutaml/uml_repository/query_dsl/conditions/block_condition.rb +46 -0
  511. data/lib/lutaml/uml_repository/query_dsl/conditions/hash_condition.rb +84 -0
  512. data/lib/lutaml/uml_repository/query_dsl/conditions/package_condition.rb +84 -0
  513. data/lib/lutaml/uml_repository/query_dsl/order.rb +90 -0
  514. data/lib/lutaml/uml_repository/query_dsl/query_builder.rb +296 -0
  515. data/lib/lutaml/uml_repository/repository.rb +764 -0
  516. data/lib/lutaml/uml_repository/repository_enhanced.rb +439 -0
  517. data/lib/lutaml/uml_repository/search_result.rb +86 -0
  518. data/lib/lutaml/uml_repository/static_site/configuration.rb +270 -0
  519. data/lib/lutaml/uml_repository/static_site/data_transformer.rb +967 -0
  520. data/lib/lutaml/uml_repository/static_site/generator.rb +401 -0
  521. data/lib/lutaml/uml_repository/static_site/id_generator.rb +115 -0
  522. data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +317 -0
  523. data/lib/lutaml/uml_repository/static_site.rb +88 -0
  524. data/lib/lutaml/uml_repository/statistics_calculator.rb +334 -0
  525. data/lib/lutaml/uml_repository/validators/repository_validator.rb +404 -0
  526. data/lib/lutaml/uml_repository/web_ui/app.rb +144 -0
  527. data/lib/lutaml/uml_repository/web_ui/public/app.js +452 -0
  528. data/lib/lutaml/uml_repository/web_ui/public/styles.css +381 -0
  529. data/lib/lutaml/uml_repository/web_ui/views/index.erb +40 -0
  530. data/lib/lutaml/uml_repository.rb +97 -0
  531. data/lib/lutaml/version.rb +3 -1
  532. data/lib/lutaml/xmi/liquid_drops/association_drop.rb +60 -58
  533. data/lib/lutaml/xmi/liquid_drops/attribute_drop.rb +55 -53
  534. data/lib/lutaml/xmi/liquid_drops/cardinality_drop.rb +15 -13
  535. data/lib/lutaml/xmi/liquid_drops/connector_drop.rb +50 -46
  536. data/lib/lutaml/xmi/liquid_drops/constraint_drop.rb +19 -17
  537. data/lib/lutaml/xmi/liquid_drops/data_type_drop.rb +93 -90
  538. data/lib/lutaml/xmi/liquid_drops/dependency_drop.rb +26 -24
  539. data/lib/lutaml/xmi/liquid_drops/diagram_drop.rb +26 -24
  540. data/lib/lutaml/xmi/liquid_drops/enum_drop.rb +40 -36
  541. data/lib/lutaml/xmi/liquid_drops/enum_owned_literal_drop.rb +20 -18
  542. data/lib/lutaml/xmi/liquid_drops/generalization_attribute_drop.rb +64 -62
  543. data/lib/lutaml/xmi/liquid_drops/generalization_drop.rb +142 -140
  544. data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +176 -161
  545. data/lib/lutaml/xmi/liquid_drops/operation_drop.rb +23 -21
  546. data/lib/lutaml/xmi/liquid_drops/package_drop.rb +96 -84
  547. data/lib/lutaml/xmi/liquid_drops/root_drop.rb +28 -25
  548. data/lib/lutaml/xmi/liquid_drops/source_target_drop.rb +39 -37
  549. data/lib/lutaml/xmi/parsers/xmi_base.rb +72 -117
  550. data/lib/lutaml/xmi/parsers/xml.rb +9 -9
  551. data/lib/lutaml/xmi.rb +37 -6
  552. data/lib/lutaml/xml/parsers/xml.rb +3 -1
  553. data/lib/lutaml/xml.rb +3 -1
  554. data/lib/lutaml.rb +14 -2
  555. data/lutaml.gemspec +16 -8
  556. data/plateau_all_packages.lur +0 -0
  557. data/templates/static_site/assets/scripts/app.js +45 -0
  558. data/templates/static_site/assets/scripts/core/state.js +419 -0
  559. data/templates/static_site/assets/scripts/core/utils.js +133 -0
  560. data/templates/static_site/assets/scripts/ui/details.js +74 -0
  561. data/templates/static_site/assets/scripts/ui/diagrams.js +345 -0
  562. data/templates/static_site/assets/scripts/ui/search.js +187 -0
  563. data/templates/static_site/assets/scripts/ui/sidebar.js +214 -0
  564. data/templates/static_site/assets/styles/00-variables.css +144 -0
  565. data/templates/static_site/assets/styles/01-reset.css +79 -0
  566. data/templates/static_site/assets/styles/02-base.css +149 -0
  567. data/templates/static_site/assets/styles/03-layout.css +171 -0
  568. data/templates/static_site/assets/styles/04-components.css +856 -0
  569. data/templates/static_site/assets/styles/05-utilities.css +89 -0
  570. data/templates/static_site/assets/styles/06-diagrams.css +277 -0
  571. data/templates/static_site/components/class_details.liquid +328 -0
  572. data/templates/static_site/components/content.liquid +508 -0
  573. data/templates/static_site/components/diagram_list.liquid +52 -0
  574. data/templates/static_site/components/diagram_viewer.liquid +71 -0
  575. data/templates/static_site/components/header.liquid +134 -0
  576. data/templates/static_site/components/package_details.liquid +119 -0
  577. data/templates/static_site/components/sidebar.liquid +46 -0
  578. data/templates/static_site/components/tree_node.liquid +81 -0
  579. data/templates/static_site/multi_file.liquid +46 -0
  580. data/templates/static_site/single_file.liquid +52 -0
  581. metadata +604 -31
  582. data/CODE_OF_CONDUCT.md +0 -74
  583. data/docs/lutaml-sysml.adoc +0 -10
@@ -0,0 +1,734 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_transformer"
4
+ require_relative "attribute_transformer"
5
+ require_relative "operation_transformer"
6
+ require_relative "constraint_transformer"
7
+ require_relative "tagged_value_transformer"
8
+ require_relative "object_property_transformer"
9
+ require_relative "generalization_transformer"
10
+ require_relative "association_transformer"
11
+ require "lutaml/uml"
12
+
13
+ module Lutaml
14
+ module Qea
15
+ module Factory
16
+ # Transforms EA objects (Class type) to UML classes
17
+ class ClassTransformer < BaseTransformer
18
+ # Transform EA object to UML class
19
+ # @param ea_object [EaObject] EA object model
20
+ # @return [Lutaml::Uml::Class] UML class
21
+ def transform(ea_object) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
22
+ return nil if ea_object.nil?
23
+
24
+ # Allow Class, Interface, and Text objects that appear on diagrams
25
+ is_class_type = ea_object.uml_class? || ea_object.interface?
26
+ is_text_class = ea_object.object_type == "Text"
27
+ return nil unless is_class_type || is_text_class
28
+
29
+ Lutaml::Uml::Class.new.tap do |klass| # rubocop:disable Metrics/BlockLength
30
+ # Map basic properties
31
+ klass.name = ea_object.name
32
+ klass.xmi_id = normalize_guid_to_xmi_format(ea_object.ea_guid,
33
+ "EAID")
34
+ klass.is_abstract = ea_object.abstract?
35
+ # Text objects exported as Class in XMI
36
+ klass.type = is_text_class ? "Class" : "Class"
37
+ klass.visibility = map_visibility(ea_object.visibility)
38
+
39
+ # Map stereotype - return string if single, array if multiple
40
+ stereotypes = []
41
+ if ea_object.stereotype && !ea_object.stereotype.empty?
42
+ stereotypes << ea_object.stereotype
43
+ end
44
+
45
+ # Check t_xref for additional stereotypes
46
+ # (only if not already added)
47
+ xref_stereotype = load_stereotype_from_xref(ea_object.ea_guid)
48
+ if xref_stereotype && !stereotypes.include?(xref_stereotype)
49
+ stereotypes << xref_stereotype
50
+ end
51
+
52
+ # Return string if single stereotype, array if multiple, nil if none
53
+ unless stereotypes.empty?
54
+ klass.stereotype = if stereotypes.size == 1
55
+ stereotypes.first
56
+ else
57
+ stereotypes
58
+ end
59
+ end
60
+
61
+ # Add "interface" stereotype if it's an interface
62
+ if ea_object.interface?
63
+ if klass.stereotype.nil?
64
+ klass.stereotype = "interface"
65
+ elsif klass.stereotype.is_a?(String)
66
+ klass.stereotype = [klass.stereotype, "interface"].uniq
67
+ elsif klass.stereotype.is_a?(Array)
68
+ unless klass.stereotype.include?("interface")
69
+ klass.stereotype << "interface"
70
+ end
71
+ end
72
+ end
73
+
74
+ # Map definition/notes
75
+ klass.definition = normalize_line_endings(ea_object.note) unless
76
+ ea_object.note.nil? || ea_object.note.empty?
77
+
78
+ # Load and transform attributes
79
+ attrs = load_attributes(ea_object.ea_object_id)
80
+ assoc_attrs = convert_to_top_element_attributes(
81
+ load_association_attributes(ea_object.ea_object_id),
82
+ )
83
+ klass.attributes = attrs + assoc_attrs
84
+
85
+ # Load and transform operations
86
+ klass.operations = load_operations(ea_object.ea_object_id)
87
+
88
+ # Load and transform constraints
89
+ klass.constraints = load_constraints(ea_object.ea_object_id)
90
+
91
+ # Load and transform tagged values
92
+ klass.tagged_values = load_tagged_values(ea_object.ea_guid)
93
+
94
+ # Load and transform object properties (as additional tagged values)
95
+ klass.tagged_values.concat(
96
+ load_object_properties(ea_object.ea_object_id),
97
+ )
98
+
99
+ # Load generalization (inheritance)
100
+ klass.generalization = load_generalization(ea_object.ea_object_id)
101
+
102
+ # Load association generalizations
103
+ klass.association_generalization = load_association_generalizations(
104
+ ea_object.ea_object_id,
105
+ )
106
+
107
+ # Load associations for this class
108
+ klass.associations = load_class_associations(
109
+ ea_object.ea_object_id, ea_object.ea_guid
110
+ )
111
+ end
112
+ end
113
+
114
+ private
115
+
116
+ # Load and transform attributes for a class
117
+ # @param object_id [Integer] Object ID
118
+ # @return [Array<Lutaml::Uml::TopElementAttribute>] UML attributes
119
+ def load_attributes(object_id)
120
+ return [] if object_id.nil?
121
+
122
+ # Query t_attribute table
123
+ query = "SELECT * FROM t_attribute WHERE Object_ID = ? ORDER BY Pos"
124
+ rows = database.connection.execute(query, object_id)
125
+
126
+ ea_attributes = rows.map do |row|
127
+ Models::EaAttribute.from_db_row(row)
128
+ end
129
+
130
+ # Transform to UML attributes
131
+ attribute_transformer = AttributeTransformer.new(database)
132
+ attribute_transformer.transform_collection(ea_attributes)
133
+ end
134
+
135
+ # Load and transform operations for a class
136
+ # @param object_id [Integer] Object ID
137
+ # @return [Array<Lutaml::Uml::Operation>] UML operations
138
+ def load_operations(object_id)
139
+ return [] if object_id.nil?
140
+
141
+ # Query t_operation table
142
+ query = "SELECT * FROM t_operation WHERE Object_ID = ? ORDER BY Pos"
143
+ rows = database.connection.execute(query, object_id)
144
+
145
+ ea_operations = rows.map do |row|
146
+ Models::EaOperation.from_db_row(row)
147
+ end
148
+
149
+ # Transform to UML operations
150
+ operation_transformer = OperationTransformer.new(database)
151
+ operation_transformer.transform_collection(ea_operations)
152
+ end
153
+
154
+ # Load and transform constraints for a class
155
+ # @param object_id [Integer] Object ID
156
+ # @return [Array<Lutaml::Uml::Constraint>] UML constraints
157
+ def load_constraints(object_id)
158
+ return [] if object_id.nil?
159
+ return [] unless database.object_constraints
160
+
161
+ # Filter constraints for this object from the in-memory collection
162
+ ea_constraints = database.object_constraints.select do |c|
163
+ c.ea_object_id == object_id
164
+ end
165
+
166
+ # Transform to UML constraints
167
+ constraint_transformer = ConstraintTransformer.new(database)
168
+ constraint_transformer.transform_collection(ea_constraints)
169
+ end
170
+
171
+ # Load and transform tagged values for a class
172
+ # @param ea_guid [String] Element GUID
173
+ # @return [Array<Lutaml::Uml::TaggedValue>] UML tagged values
174
+ def load_tagged_values(ea_guid)
175
+ return [] if ea_guid.nil?
176
+ return [] unless database.tagged_values
177
+
178
+ # Filter tagged values for this element from the in-memory collection
179
+ ea_tags = database.tagged_values.select do |tag|
180
+ tag.element_id == ea_guid
181
+ end
182
+
183
+ # Transform to UML tagged values
184
+ tag_transformer = TaggedValueTransformer.new(database)
185
+ tag_transformer.transform_collection(ea_tags)
186
+ end
187
+
188
+ # Load and transform object properties for a class
189
+ # @param object_id [Integer] Object ID
190
+ # @return [Array<Lutaml::Uml::TaggedValue>] UML tagged values
191
+ def load_object_properties(object_id)
192
+ return [] if object_id.nil?
193
+ return [] unless database.object_properties
194
+
195
+ # Filter object properties for this object from the in-memory
196
+ # collection
197
+ ea_props = database.object_properties.select do |prop|
198
+ prop.ea_object_id == object_id
199
+ end
200
+
201
+ # Transform to UML tagged values
202
+ prop_transformer = ObjectPropertyTransformer.new(database)
203
+ prop_transformer.transform_collection(ea_props)
204
+ end
205
+
206
+ # Load stereotype from t_xref table
207
+ # @param ea_guid [String] Element GUID
208
+ # @return [String, nil] Stereotype value
209
+ def load_stereotype_from_xref(ea_guid) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
210
+ return nil if ea_guid.nil?
211
+ return nil unless database.xrefs
212
+
213
+ # Find stereotype xref from the in-memory collection
214
+ xref = database.xrefs.find do |x|
215
+ x.client == ea_guid && x.name == "Stereotypes" &&
216
+ x.type == "element property"
217
+ end
218
+
219
+ return nil unless xref
220
+
221
+ # Parse stereotype from Description field
222
+ # Format: @STEREO;Name=FeatureType;FQName=...;@ENDSTEREO;
223
+ description = xref.description
224
+ return nil if description.nil? || description.empty?
225
+
226
+ # Extract the Name value from the @STEREO format
227
+ if description =~ /@STEREO;Name=([^;]+);/
228
+ return $1
229
+ end
230
+
231
+ nil
232
+ end
233
+
234
+ # Load generalization for a class
235
+ # @param object_id [Integer] Object ID
236
+ # @param visited [Set] Set of visited object IDs to prevent
237
+ # circular references
238
+ # @param is_leaf [Boolean] Whether this is the leaf class
239
+ # (not a parent in recursion)
240
+ # @return [Lutaml::Uml::Generalization, nil] UML generalization or nil
241
+ def load_generalization(object_id, visited = Set.new, is_leaf = true) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity,Style/OptionalBooleanParameter
242
+ return nil if object_id.nil?
243
+
244
+ # Detect circular reference
245
+ if visited.include?(object_id)
246
+ warn "Circular inheritance detected for object_id #{object_id}, " \
247
+ "stopping recursion"
248
+ return nil
249
+ end
250
+
251
+ # Add current object to visited set
252
+ visited = visited.dup.add(object_id)
253
+
254
+ # 1. Load CURRENT object
255
+ current_obj = find_object_by_id(object_id)
256
+ return nil unless current_obj
257
+
258
+ # 2. Find generalization connector where this class is the subtype
259
+ query = "SELECT * FROM t_connector WHERE Start_Object_ID = ? " \
260
+ "AND Connector_Type = 'Generalization' LIMIT 1"
261
+ rows = database.connection.execute(query, object_id)
262
+
263
+ # 3. Create generalization object for current class
264
+ # Even if no parent exists, we need a Generalization
265
+ # representing this class
266
+ if rows.empty?
267
+ # No parent - create terminal generalization
268
+ gen_transformer = GeneralizationTransformer.new(database)
269
+ generalization = gen_transformer.transform(nil, current_obj)
270
+ else
271
+ # Has parent - create generalization with parent connector
272
+ ea_connector = Models::EaConnector.from_db_row(rows.first)
273
+ gen_transformer = GeneralizationTransformer.new(database)
274
+ generalization = gen_transformer
275
+ .transform(ea_connector, current_obj)
276
+ end
277
+ return nil unless generalization
278
+
279
+ # 4. Load CURRENT object attributes and convert to GeneralAttribute
280
+ current_attrs = load_attributes(object_id)
281
+ current_assoc_attrs = load_association_attributes(object_id)
282
+ general_attrs = convert_to_general_attributes(
283
+ current_attrs + current_assoc_attrs,
284
+ )
285
+
286
+ # Set gen_name and name_ns on general_attributes
287
+ # (matches current class context)
288
+ upper_klass = generalization.general_upper_klass
289
+ gen_name = generalization.general_name
290
+ general_attrs.each do |attr|
291
+ attr.gen_name = gen_name
292
+ # Determine name_ns based on type_ns
293
+ # (same logic as transform_general_attributes)
294
+ name_ns = case attr.type_ns
295
+ when "core", "gml"
296
+ upper_klass
297
+ else
298
+ attr.type_ns
299
+ end
300
+ attr.name_ns = name_ns || upper_klass
301
+ end
302
+
303
+ generalization.general_attributes = general_attrs
304
+ .sort_by { |a| [a.name.to_s, a.id] }
305
+
306
+ # 5. Transform attributes (set name_ns, gen_name) -
307
+ # creates working copies
308
+ generalization.attributes = transform_general_attributes(
309
+ generalization,
310
+ )
311
+
312
+ # 6. Partition into owned_props and assoc_props
313
+ generalization.owned_props = generalization.attributes
314
+ .reject(&:has_association)
315
+ generalization.assoc_props = generalization.attributes
316
+ .select(&:has_association)
317
+
318
+ # 7. Recursively load PARENT generalization with circular
319
+ # reference detection
320
+ # Pass is_leaf=false so parent doesn't populate inherited_props
321
+ parent_object_id = ea_connector&.end_object_id
322
+ if parent_object_id
323
+ parent_gen = load_generalization(parent_object_id, visited, false)
324
+ if parent_gen
325
+ generalization.general = parent_gen
326
+ generalization.has_general = true
327
+ end
328
+ end
329
+
330
+ # 8. Collect inherited properties from ancestor chain
331
+ # Only populate inherited_props at the LEAF level
332
+ # (matches XMI behavior)
333
+ if is_leaf && generalization.has_general
334
+ collect_inherited_properties(generalization)
335
+ end
336
+
337
+ generalization
338
+ end
339
+
340
+ # Convert TopElementAttribute array to GeneralAttribute array
341
+ # @param attributes [Array<Lutaml::Uml::TopElementAttribute>]
342
+ # @return [Array<Lutaml::Uml::GeneralAttribute>]
343
+ def convert_to_general_attributes(attributes) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
344
+ attributes.map do |attr|
345
+ Lutaml::Uml::GeneralAttribute.new.tap do |gen_attr|
346
+ gen_attr.id = attr.id
347
+ gen_attr.name = attr.name
348
+ gen_attr.type = attr.type
349
+ gen_attr.xmi_id = attr.xmi_id
350
+ gen_attr.is_derived = !!attr.is_derived
351
+ gen_attr.cardinality = attr.cardinality
352
+ gen_attr.definition = attr.definition&.strip
353
+ gen_attr.association = attr.association
354
+ gen_attr.has_association = !!attr.association
355
+ gen_attr.type_ns = attr.type_ns
356
+ end
357
+ end
358
+ end
359
+
360
+ # Convert GeneralAttribute array to TopElementAttribute array
361
+ # @param attributes [Array<Lutaml::Uml::TopElementAttribute>]
362
+ # @return [Array<Lutaml::Uml::TopElementAttribute>]
363
+ def convert_to_top_element_attributes(attributes) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
364
+ attributes.map do |attr|
365
+ Lutaml::Uml::TopElementAttribute.new.tap do |top_attr|
366
+ top_attr.id = attr.id
367
+ top_attr.name = attr.name
368
+ top_attr.type = attr.type
369
+ top_attr.xmi_id = attr.xmi_id
370
+ top_attr.cardinality = attr.cardinality
371
+ top_attr.definition = attr.definition&.strip
372
+ top_attr.association = attr.association
373
+ top_attr.type_ns = attr.type_ns
374
+ top_attr.is_derived = !!attr.is_derived
375
+ end
376
+ end
377
+ end
378
+
379
+ # Transform GeneralAttributes with context (name_ns, gen_name)
380
+ # Similar to XMI's create_uml_attributes
381
+ # @param generalization [Lutaml::Uml::Generalization]
382
+ # @return [Array<Lutaml::Uml::GeneralAttribute>]
383
+ def transform_general_attributes(generalization) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
384
+ upper_klass = generalization.general_upper_klass
385
+ gen_name = generalization.general_name
386
+ gen_attrs = generalization.general_attributes
387
+
388
+ gen_attrs.map do |attr|
389
+ # Clone to avoid mutation
390
+ transformed = attr.dup
391
+
392
+ # Set name_ns based on type_ns
393
+ name_ns = case attr.type_ns
394
+ when "core", "gml"
395
+ upper_klass
396
+ else
397
+ attr.type_ns
398
+ end
399
+ name_ns = upper_klass if name_ns.nil?
400
+
401
+ transformed.name_ns = name_ns
402
+ transformed.gen_name = gen_name
403
+ transformed.name = "" if transformed.name.nil?
404
+
405
+ transformed
406
+ end
407
+ end
408
+
409
+ # Collect inherited properties from ancestor chain
410
+ # Similar to XMI's loop_general_item
411
+ # @param generalization [Lutaml::Uml::Generalization]
412
+ # @return [void] (modifies generalization in place)
413
+ def collect_inherited_properties(generalization) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
414
+ inherited_props = []
415
+ inherited_assoc_props = []
416
+ level = 0
417
+
418
+ # Walk the general chain
419
+ current_gen = generalization.general
420
+ while current_gen
421
+ # Set metadata on BOTH general_attributes and attributes
422
+ # (matches XMI behavior)
423
+ # upper_klass and level are set during the inheritance walk
424
+ [current_gen.general_attributes,
425
+ current_gen.attributes].each do |attr_list|
426
+ attr_list&.each do |attr|
427
+ attr.upper_klass = current_gen.general_upper_klass
428
+ attr.level = level
429
+ end
430
+ end
431
+
432
+ # Process each attribute in reverse order
433
+ # (to show super class first after reversal)
434
+ current_gen.attributes.reverse_each do |attr|
435
+ # Clone attribute for inherited collection
436
+ inherited_attr = attr.dup
437
+ inherited_attr.upper_klass = current_gen.general_upper_klass
438
+ inherited_attr.gen_name = current_gen.general_name
439
+ inherited_attr.level = level
440
+
441
+ # Partition by association
442
+ if attr.has_association
443
+ inherited_assoc_props << inherited_attr
444
+ else
445
+ inherited_props << inherited_attr
446
+ end
447
+ end
448
+
449
+ # Move to next level
450
+ level += 1
451
+ current_gen = current_gen.general
452
+ end
453
+
454
+ # Reverse to show super class first
455
+ generalization.inherited_props = inherited_props.reverse
456
+ generalization.inherited_assoc_props = inherited_assoc_props.reverse
457
+ end
458
+
459
+ # Load association generalizations for a class
460
+ # @param object_id [Integer] Object ID
461
+ # @return [Array<Lutaml::Uml::AssociationGeneralization>]
462
+ # UML association generalizations
463
+ def load_association_generalizations(object_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
464
+ return [] if object_id.nil?
465
+
466
+ # Query for ALL generalization connectors for this class
467
+ query = "SELECT ea_guid, End_Object_ID FROM t_connector " \
468
+ "WHERE Start_Object_ID = ? " \
469
+ "AND Connector_Type = 'Generalization'"
470
+ rows = database.connection.execute(query, object_id)
471
+
472
+ rows.filter_map do |row|
473
+ guid = row.is_a?(Hash) ? (row["ea_guid"] || row[:ea_guid]) : row[0]
474
+ parent_object_id = if row.is_a?(Hash)
475
+ row["End_Object_ID"] || row[:End_Object_ID]
476
+ else
477
+ row[1]
478
+ end
479
+
480
+ # Find parent object to get its GUID
481
+ parent_obj = find_object_by_id(parent_object_id)
482
+ next unless parent_obj
483
+
484
+ Lutaml::Uml::AssociationGeneralization.new.tap do |ag|
485
+ ag.id = normalize_guid_to_xmi_format(guid, "EAID")
486
+ ag.type = "uml:Generalization"
487
+ ag.general = normalize_guid_to_xmi_format(parent_obj.ea_guid,
488
+ "EAID")
489
+ end
490
+ end
491
+ end
492
+
493
+ # Load associations for a class
494
+ # Creates Association objects from navigable association ends
495
+ # (ownedAttributes with association markers)
496
+ # This matches XMI behavior where current class is always the owner
497
+ # @param object_id [Integer] Object ID
498
+ # @param object_guid [String] Object GUID
499
+ # @return [Array<Lutaml::Uml::Association>] UML associations
500
+ def load_class_associations(object_id, object_guid) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
501
+ return [] if object_id.nil?
502
+
503
+ associations = []
504
+ normalized_owner_xmi_id = normalize_guid_to_xmi_format(object_guid,
505
+ "EAID")
506
+
507
+ # Find all association-type connectors where this class participates
508
+ query = "SELECT * FROM t_connector " \
509
+ "WHERE (Start_Object_ID = ? OR End_Object_ID = ?) " \
510
+ "AND Connector_Type IN " \
511
+ "('Association', 'Aggregation', 'Composition')"
512
+ rows = database.connection.execute(query, [object_id, object_id])
513
+
514
+ rows.each do |row| # rubocop:disable Metrics/BlockLength
515
+ ea_connector = Models::EaConnector.from_db_row(row)
516
+
517
+ # Determine which end this class is on
518
+ is_start = ea_connector.start_object_id == object_id
519
+
520
+ # Get role name (this is the ownedAttribute name)
521
+ owner_end_attribute_name = if is_start
522
+ ea_connector.destrole
523
+ else
524
+ ea_connector.sourcerole
525
+ end
526
+
527
+ # Only create association if there's a navigable role name
528
+ # (matches XMI ownedAttribute[@association])
529
+ if owner_end_attribute_name.nil? || owner_end_attribute_name.empty?
530
+ next
531
+ end
532
+
533
+ # Get member end (the other class)
534
+ member_obj = if is_start
535
+ find_object_by_id(ea_connector.end_object_id)
536
+ else
537
+ find_object_by_id(ea_connector.start_object_id)
538
+ end
539
+ next unless member_obj
540
+
541
+ # Get member end attribute name
542
+ # (role at the opposite end, or class name if no role)
543
+ member_end_attribute_name = if is_start
544
+ ea_connector.sourcerole
545
+ else
546
+ ea_connector.destrole
547
+ end
548
+ if member_end_attribute_name.nil? ||
549
+ member_end_attribute_name.empty?
550
+ member_end_attribute_name = member_obj.name
551
+ end
552
+
553
+ # Get cardinality for this end
554
+ member_cardinality_str = if is_start
555
+ ea_connector.destcard
556
+ else
557
+ ea_connector.sourcecard
558
+ end
559
+
560
+ # Create association from this class's perspective
561
+ associations << Lutaml::Uml::Association.new.tap do |assoc| # rubocop:disable Metrics/BlockLength
562
+ assoc.xmi_id = normalize_guid_to_xmi_format(ea_connector.ea_guid,
563
+ "EAID")
564
+ unless ea_connector.name.nil? || ea_connector.name.empty?
565
+ assoc.name = ea_connector.name
566
+ end
567
+
568
+ # Owner is always the current class (matches XMI)
569
+ assoc.owner_end = find_object_by_id(object_id)&.name
570
+ assoc.owner_end_xmi_id = normalized_owner_xmi_id
571
+ assoc.owner_end_attribute_name = owner_end_attribute_name
572
+
573
+ # Member is the other end
574
+ assoc.member_end = member_obj.name
575
+ assoc.member_end_xmi_id = normalize_guid_to_xmi_format(
576
+ member_obj.ea_guid, "EAID"
577
+ )
578
+ assoc.member_end_attribute_name = member_end_attribute_name
579
+
580
+ # Set member_end_type based on connector type
581
+ ea_type = ea_connector.connector_type
582
+ assoc.member_end_type = ea_type&.downcase
583
+
584
+ # Set cardinality
585
+ if member_cardinality_str && !member_cardinality_str.empty?
586
+ parsed = parse_cardinality(member_cardinality_str)
587
+ if parsed[:min] || parsed[:max]
588
+ assoc.member_end_cardinality = Lutaml::Uml::Cardinality.new
589
+ .tap do |card|
590
+ card.min = parsed[:min]
591
+ card.max = parsed[:max]
592
+ end
593
+ end
594
+ end
595
+
596
+ # Note: XMI does not include connector notes
597
+ # in Association definition
598
+ end
599
+ end
600
+
601
+ associations.compact
602
+ end
603
+
604
+ # Load association-based attributes
605
+ # (navigable association ends with role names)
606
+ # @param object_id [Integer] Object ID
607
+ # @return [Array<Lutaml::Uml::TopElementAttribute>]
608
+ # Association-based attributes
609
+ def load_association_attributes(object_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
610
+ return [] if object_id.nil?
611
+
612
+ attributes = []
613
+
614
+ # Find all association-type connectors
615
+ # (Association, Aggregation, Composition)
616
+ query = "SELECT * FROM t_connector " \
617
+ "WHERE (Start_Object_ID = ? OR End_Object_ID = ?) " \
618
+ "AND Connector_Type IN " \
619
+ "('Association', 'Aggregation', 'Composition')"
620
+ rows = database.connection.execute(query, [object_id, object_id])
621
+ obj = find_object_by_id(object_id)
622
+ obj_pkg_name = find_package_name(obj&.package_id)
623
+
624
+ rows.each do |row| # rubocop:disable Metrics/BlockLength
625
+ ea_connector = Models::EaConnector.from_db_row(row)
626
+
627
+ # Check if this object is the source (owner) or target (member)
628
+ if ea_connector.start_object_id == object_id
629
+ # This class is the source - check for dest role
630
+ next if ea_connector.destrole.nil? || ea_connector.destrole.empty?
631
+
632
+ target_obj = find_object_by_id(ea_connector.end_object_id)
633
+ next unless target_obj
634
+
635
+ target_obj_pkg_name = find_package_name(target_obj.package_id)
636
+
637
+ attributes << create_association_attribute(
638
+ name: ea_connector.destrole,
639
+ type: target_obj.name,
640
+ type_xmi_id: target_obj.ea_guid,
641
+ association_xmi_id: ea_connector.ea_guid,
642
+ cardinality: ea_connector.destcard,
643
+ definition: ea_connector.notes,
644
+ gen_name: obj.name,
645
+ name_ns: obj_pkg_name,
646
+ type_ns: target_obj_pkg_name,
647
+ is_src: false,
648
+ )
649
+ elsif ea_connector.end_object_id == object_id
650
+ # This class is the target - check for source role
651
+ if ea_connector.sourcerole.nil? || ea_connector.sourcerole.empty?
652
+ next
653
+ end
654
+
655
+ source_obj = find_object_by_id(ea_connector.start_object_id)
656
+ next unless source_obj
657
+
658
+ source_obj_pkg_name = find_package_name(source_obj.package_id)
659
+
660
+ attributes << create_association_attribute(
661
+ name: ea_connector.sourcerole,
662
+ type: source_obj.name,
663
+ type_xmi_id: source_obj.ea_guid,
664
+ association_xmi_id: ea_connector.ea_guid,
665
+ cardinality: ea_connector.sourcecard,
666
+ definition: ea_connector.notes,
667
+ gen_name: obj.name,
668
+ name_ns: obj_pkg_name,
669
+ type_ns: source_obj_pkg_name,
670
+ )
671
+ end
672
+ end
673
+
674
+ attributes.compact
675
+ end
676
+
677
+ # Create an attribute from association end
678
+ # @param name [String] Attribute name (role name)
679
+ # @param type [String] Attribute type (class name)
680
+ # @param type_xmi_id [String] Type XMI ID
681
+ # @param association_xmi_id [String] Association XMI ID
682
+ # @param cardinality [String] Cardinality string
683
+ # @param gen_name [String] Name of the generalization object
684
+ # @return [Lutaml::Uml::GeneralAttribute] Created attribute
685
+ def create_association_attribute( # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/ParameterLists
686
+ name:, type:, type_xmi_id:,
687
+ association_xmi_id:, cardinality:, definition:,
688
+ gen_name:, name_ns:, type_ns:, is_src: true
689
+ )
690
+ Lutaml::Uml::GeneralAttribute.new.tap do |attr|
691
+ attr.name = name
692
+ attr.type = type
693
+ attr.gen_name = gen_name
694
+ attr.definition = definition
695
+ attr.xmi_id = normalize_guid_to_xmi_format(type_xmi_id, "EAID")
696
+ attr.association = normalize_guid_to_xmi_format(
697
+ association_xmi_id, "EAID"
698
+ )
699
+ attr.has_association = true
700
+ attr.id = normalize_guid_to_xmi_src_dst_format(
701
+ association_xmi_id, "EAID", is_src
702
+ )
703
+ attr.name_ns = name_ns
704
+ attr.type_ns = type_ns
705
+
706
+ # Map cardinality if present
707
+ if cardinality && !cardinality.empty?
708
+ parsed = parse_cardinality(cardinality)
709
+ if parsed[:min] || parsed[:max]
710
+ attr.cardinality = Lutaml::Uml::Cardinality.new.tap do |card|
711
+ card.min = parsed[:min]
712
+ card.max = parsed[:max]
713
+ end
714
+ end
715
+ end
716
+ end
717
+ end
718
+
719
+ # Find package name by ID
720
+ # @param package_id [Integer] Package ID
721
+ # @return [String, Nil] Package name or nil
722
+ def find_package_name(package_id)
723
+ return nil if package_id.nil?
724
+
725
+ query = "SELECT NAME FROM t_package WHERE Package_ID = ?"
726
+ rows = database.connection.execute(query, [package_id])
727
+ return nil if rows.empty?
728
+
729
+ rows.first["Name"]
730
+ end
731
+ end
732
+ end
733
+ end
734
+ end