lutaml 0.9.43 → 0.10.1

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