lutaml 0.9.43 → 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 +40 -19
  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 -37
  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 +174 -170
  545. data/lib/lutaml/xmi/liquid_drops/operation_drop.rb +23 -21
  546. data/lib/lutaml/xmi/liquid_drops/package_drop.rb +95 -93
  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 +27 -17
  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,460 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../uml/package_path"
4
+ require_relative "../uml/qualified_name"
5
+
6
+ module Lutaml
7
+ module UmlRepository
8
+ # IndexBuilder builds fast lookup indexes from a Lutaml::Uml::Document
9
+ #
10
+ # This class creates immutable hash indexes that enable O(1) lookups for:
11
+ # - Package paths (e.g., "ModelRoot::i-UR::urf")
12
+ # - Qualified names (e.g., "ModelRoot::i-UR::urf::Building")
13
+ # - Stereotypes (e.g., "featureType" => [Class, Class, ...])
14
+ # - Inheritance graph (parent_qname => [child_qname, ...])
15
+ # - Diagram index (package_id => [Diagram, ...])
16
+ # - Package to path mapping (package_id => path)
17
+ # - Class to qualified name mapping (class_id => qualified_name)
18
+ # - Classes (class_id => Class)
19
+ # - Associations (association_id => Association)
20
+ #
21
+ # All indexes are frozen to ensure immutability.
22
+ #
23
+ # @example Building all indexes from a document
24
+ # indexes = IndexBuilder.build_all(document)
25
+ # package = indexes[:package_paths]["ModelRoot::i-UR"]
26
+ # klass = indexes[:qualified_names]["ModelRoot::i-UR::Building"]
27
+ class IndexBuilder
28
+ ROOT_PACKAGE_NAME = "ModelRoot"
29
+
30
+ # Build all indexes from a UML document
31
+ #
32
+ # @param document [Lutaml::Uml::Document] The UML document to index
33
+ # @return [Hash] A frozen hash containing all indexes with keys:
34
+ # - :package_paths - Maps package paths to Package objects
35
+ # - :qualified_names - Maps qualified names to
36
+ # Class/DataType/Enum objects
37
+ # - :stereotypes - Groups classes by stereotype
38
+ # - :inheritance_graph - Maps parent qualified names to child
39
+ # qualified names
40
+ # - :diagram_index - Maps package IDs/paths to Diagram objects
41
+ # - :package_to_path - Maps package XMI IDs to paths
42
+ # - :class_to_qname - Maps class XMI IDs to qualified names
43
+ # - :classes - Maps class XMI IDs to Class objects
44
+ # - :associations - Maps association XMI IDs to Association objects
45
+ def self.build_all(document) # rubocop:disable Metrics/MethodLength
46
+ {
47
+ package_paths: build_package_paths(document),
48
+ qualified_names: build_qualified_names(document),
49
+ stereotypes: build_stereotypes(document),
50
+ inheritance_graph: build_inheritance_graph(document, nil),
51
+ diagram_index: build_diagram_index(document, nil),
52
+ package_to_path: build_package_to_path(document),
53
+ class_to_qname: build_class_to_qname(document),
54
+ classes: build_classes(document),
55
+ associations: build_associations(document),
56
+ }.freeze
57
+ end
58
+
59
+ # Build package paths index
60
+ #
61
+ # @param document [Lutaml::Uml::Document] The UML document
62
+ # @return [Hash] Frozen hash mapping package paths to Package objects
63
+ def self.build_package_paths(document)
64
+ builder = new(document)
65
+ builder.build_package_path_index
66
+ builder.instance_variable_get(:@package_paths).freeze
67
+ end
68
+
69
+ def self.build_package_to_path(document)
70
+ builder = new(document)
71
+ builder.build_package_path_index
72
+ builder.instance_variable_get(:@package_to_path).freeze
73
+ end
74
+
75
+ # Build qualified names index
76
+ #
77
+ # @param document [Lutaml::Uml::Document] The UML document
78
+ # @return [Hash] Frozen hash mapping qualified names to Class objects
79
+ def self.build_qualified_names(document)
80
+ builder = new(document)
81
+ builder.build_qualified_name_index
82
+ builder.instance_variable_get(:@qualified_names).freeze
83
+ end
84
+
85
+ def self.build_class_to_qname(document)
86
+ builder = new(document)
87
+ builder.build_qualified_name_index
88
+ builder.instance_variable_get(:@class_to_qname).freeze
89
+ end
90
+
91
+ def self.build_classes(document)
92
+ builder = new(document)
93
+ builder.build_qualified_name_index
94
+ builder.instance_variable_get(:@classes).freeze
95
+ end
96
+
97
+ def self.build_associations(document)
98
+ builder = new(document)
99
+ # build_association_index needs @qualified_names to collect
100
+ # class-level associations
101
+ builder.build_qualified_name_index
102
+ builder.build_association_index
103
+ builder.instance_variable_get(:@associations).freeze
104
+ end
105
+
106
+ # Build stereotypes index
107
+ #
108
+ # @param document [Lutaml::Uml::Document] The UML document
109
+ # @return [Hash] Frozen hash grouping classes by stereotype
110
+ def self.build_stereotypes(document)
111
+ builder = new(document)
112
+ builder.build_stereotype_index
113
+ builder.instance_variable_get(:@stereotypes).freeze
114
+ end
115
+
116
+ # Build inheritance graph index
117
+ #
118
+ # @param document [Lutaml::Uml::Document] The UML document
119
+ # @param indexes [Hash, nil] Existing indexes (requires :qualified_names)
120
+ # @return [Hash] Frozen hash mapping parent qnames to child qnames
121
+ def self.build_inheritance_graph(document, indexes)
122
+ builder = new(document)
123
+ # If qualified_names index is provided, use it
124
+ if indexes && indexes[:qualified_names]
125
+ builder.instance_variable_set(:@qualified_names,
126
+ indexes[:qualified_names])
127
+ else
128
+ builder.build_qualified_name_index
129
+ end
130
+ builder.build_inheritance_graph_index
131
+ builder.instance_variable_get(:@inheritance_graph).freeze
132
+ end
133
+
134
+ # Build diagram index
135
+ #
136
+ # @param document [Lutaml::Uml::Document] The UML document
137
+ # @param indexes [Hash, nil] Existing indexes (requires :package_paths)
138
+ # @return [Hash] Frozen hash mapping package IDs to Diagram objects
139
+ def self.build_diagram_index(document, indexes)
140
+ builder = new(document)
141
+ # If package_paths index is provided, use it
142
+ if indexes && indexes[:package_paths]
143
+ builder.instance_variable_set(:@package_paths,
144
+ indexes[:package_paths])
145
+ else
146
+ builder.build_package_path_index
147
+ end
148
+ builder.build_diagram_index
149
+ builder.instance_variable_get(:@diagram_index).freeze
150
+ end
151
+
152
+ def initialize(document)
153
+ @document = document
154
+ @package_paths = {}
155
+ @qualified_names = {}
156
+ @stereotypes = {}
157
+ @inheritance_graph = {}
158
+ @diagram_index = {}
159
+ @package_to_path = {}
160
+ @class_to_qname = {}
161
+ @classes = {}
162
+ @associations = {}
163
+ end
164
+
165
+ # Build all indexes and return them as a frozen hash
166
+ #
167
+ # @return [Hash] Frozen hash containing all indexes
168
+ def build_all # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
169
+ build_package_path_index
170
+ build_qualified_name_index
171
+ build_stereotype_index
172
+ build_inheritance_graph_index
173
+ build_diagram_index
174
+ build_association_index
175
+
176
+ {
177
+ package_paths: @package_paths.freeze,
178
+ qualified_names: @qualified_names.freeze,
179
+ stereotypes: @stereotypes.freeze,
180
+ inheritance_graph: @inheritance_graph.freeze,
181
+ diagram_index: @diagram_index.freeze,
182
+ package_to_path: @package_to_path.freeze,
183
+ class_to_qname: @class_to_qname.freeze,
184
+ classes: @classes.freeze,
185
+ associations: @associations.freeze,
186
+ }.freeze
187
+ end
188
+
189
+ # Build the package path index
190
+ #
191
+ # Creates a hash mapping package paths to Package objects:
192
+ # "ModelRoot" => Package{},
193
+ # "ModelRoot::i-UR" => Package{},
194
+ # "ModelRoot::i-UR::urf" => Package{}
195
+ # @api public
196
+ def build_package_path_index
197
+ # Add root package if it exists
198
+ @package_paths[ROOT_PACKAGE_NAME] = @document if @document
199
+
200
+ # Traverse all packages recursively
201
+ traverse_packages(@document.packages,
202
+ parent_path: ROOT_PACKAGE_NAME) do |package, path|
203
+ @package_paths[path] = package
204
+ @package_to_path[package.xmi_id] = path if package.xmi_id
205
+ end
206
+ end
207
+
208
+ # Build the qualified name index
209
+ #
210
+ # Creates a hash mapping qualified names to Class/DataType/Enum objects:
211
+ # "ModelRoot::i-UR::urf::Building" => Class{}
212
+ # @api public
213
+ def build_qualified_name_index # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
214
+ # Index top-level classes, data_types, and enums from document
215
+ if @document.classes
216
+ index_classifiers(@document.classes,
217
+ ROOT_PACKAGE_NAME)
218
+ end
219
+ if @document.data_types
220
+ index_classifiers(@document.data_types,
221
+ ROOT_PACKAGE_NAME)
222
+ end
223
+ index_classifiers(@document.enums, ROOT_PACKAGE_NAME) if @document.enums
224
+
225
+ # Traverse packages and index their classifiers
226
+ traverse_packages(@document.packages,
227
+ parent_path: ROOT_PACKAGE_NAME) do |package, path|
228
+ index_classifiers(package.classes, path) if package.classes
229
+ index_classifiers(package.data_types, path) if package.data_types
230
+ index_classifiers(package.enums, path) if package.enums
231
+ end
232
+ end
233
+
234
+ def build_association_index # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
235
+ # Collect document-level associations (XMI format)
236
+ @document.associations&.each do |assoc|
237
+ next unless assoc.xmi_id
238
+
239
+ @associations[assoc.xmi_id] = assoc
240
+ end
241
+
242
+ # Collect class-level associations (QEA/EA format)
243
+ # Note: This requires qualified_names index to be built first
244
+ @qualified_names.each_value do |klass|
245
+ next unless klass.respond_to?(:associations) && klass.associations
246
+
247
+ klass.associations.each do |assoc|
248
+ next unless assoc.xmi_id
249
+
250
+ # Avoid duplicates - only add if not already present
251
+ @associations[assoc.xmi_id] ||= assoc
252
+ end
253
+ end
254
+ end
255
+
256
+ # Build the stereotype index
257
+ #
258
+ # Creates a hash grouping classes by their stereotype:
259
+ # "featureType" => [Class{}, Class{}],
260
+ # "dataType" => [Class{}]
261
+ # @api public
262
+ def build_stereotype_index # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
263
+ # Process top-level classes
264
+ index_by_stereotype(@document.classes) if @document.classes
265
+ index_by_stereotype(@document.data_types) if @document.data_types
266
+ index_by_stereotype(@document.enums) if @document.enums
267
+
268
+ # Process classes in packages
269
+ traverse_packages(@document.packages) do |package, _path|
270
+ index_by_stereotype(package.classes) if package.classes
271
+ index_by_stereotype(package.data_types) if package.data_types
272
+ index_by_stereotype(package.enums) if package.enums
273
+ end
274
+ end
275
+
276
+ # Build the inheritance graph index
277
+ #
278
+ # Creates a hash mapping parent qualified names to arrays of
279
+ # child qualified names:
280
+ # "ModelRoot::Parent" => ["ModelRoot::Child1", "ModelRoot::Child2"]
281
+ # @api public
282
+ def build_inheritance_graph_index
283
+ # Process top-level classes
284
+ if @document.classes
285
+ process_generalizations(@document.classes,
286
+ ROOT_PACKAGE_NAME)
287
+ end
288
+
289
+ # Process classes in packages
290
+ traverse_packages(@document.packages,
291
+ parent_path: ROOT_PACKAGE_NAME) do |package, path|
292
+ process_generalizations(package.classes, path) if package.classes
293
+ end
294
+ end
295
+
296
+ # Build the diagram index
297
+ #
298
+ # Creates a hash mapping package IDs/paths to arrays of Diagram objects:
299
+ # "package_id" => [Diagram{}, Diagram{}]
300
+ # @api public
301
+ def build_diagram_index
302
+ # Traverse packages and collect diagrams
303
+ traverse_packages(@document.packages) do |package, path|
304
+ next unless package.diagrams && !package.diagrams.empty?
305
+
306
+ # Index by package ID if available, otherwise by path
307
+ key = package.xmi_id || path
308
+ @diagram_index[key] ||= []
309
+ @diagram_index[key].concat(package.diagrams)
310
+ end
311
+ end
312
+
313
+ # Traverse packages recursively, yielding each package with its path
314
+ #
315
+ # @param packages [Array<Lutaml::Uml::Package>] Packages to traverse
316
+ # @param parent_path [String, nil] Parent package path
317
+ # @yield [package, path] Yields each package with its full path
318
+ def traverse_packages(packages, parent_path: nil, &block)
319
+ return unless packages
320
+
321
+ packages.each do |package|
322
+ path = build_package_path(package.name, parent_path)
323
+ yield package, path if block
324
+
325
+ # Recursively traverse nested packages
326
+ if package.packages
327
+ traverse_packages(package.packages, parent_path: path,
328
+ &block)
329
+ end
330
+ end
331
+ end
332
+
333
+ # Build a package path from a package name and parent path
334
+ #
335
+ # @param name [String] Package name
336
+ # @param parent_path [String, nil] Parent package path
337
+ # @return [String] Full package path
338
+ def build_package_path(name, parent_path)
339
+ return name unless parent_path
340
+
341
+ "#{parent_path}::#{name}"
342
+ end
343
+
344
+ # Index classifiers (classes, data types, enums) by their qualified names
345
+ #
346
+ # @param classifiers [Array] Array of classifier objects
347
+ # @param package_path [String] Package path for these classifiers
348
+ def index_classifiers(classifiers, package_path) # rubocop:disable Metrics/MethodLength
349
+ return unless classifiers
350
+
351
+ classifiers.each do |classifier|
352
+ next unless classifier.name
353
+
354
+ qualified_name = "#{package_path}::#{classifier.name}"
355
+ @qualified_names[qualified_name] = classifier
356
+ if classifier.xmi_id
357
+ @class_to_qname[classifier.xmi_id] =
358
+ qualified_name
359
+ end
360
+ @classes[classifier.xmi_id] = classifier if classifier.xmi_id
361
+ end
362
+ end
363
+
364
+ # Index classifiers by their stereotypes
365
+ #
366
+ # @param classifiers [Array] Array of classifier objects
367
+ def index_by_stereotype(classifiers) # rubocop:disable Metrics/CyclomaticComplexity
368
+ return unless classifiers
369
+
370
+ classifiers.each do |classifier|
371
+ next unless classifier.stereotype && !classifier.stereotype.empty?
372
+
373
+ # Handle both String and Array stereotypes
374
+ stereotypes = Array(classifier.stereotype)
375
+ stereotypes.each do |stereotype|
376
+ @stereotypes[stereotype] ||= []
377
+ @stereotypes[stereotype] << classifier
378
+ end
379
+ end
380
+ end
381
+
382
+ # Process generalization relationships to build inheritance graph
383
+ #
384
+ # @param classes [Array<Lutaml::Uml::Class>] Classes to process
385
+ # @param package_path [String] Package path for these classes
386
+ def process_generalizations(classes, package_path) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
387
+ return unless classes
388
+
389
+ classes.each do |klass|
390
+ next unless klass.name
391
+ next unless klass.generalization
392
+
393
+ child_qname = "#{package_path}::#{klass.name}"
394
+
395
+ # Handle generalization - it could have a general attribute
396
+ parent_name = extract_parent_name(klass.generalization)
397
+ next unless parent_name
398
+
399
+ # Try to resolve parent qualified name
400
+ parent_qname = resolve_qualified_name(parent_name, package_path)
401
+ next unless parent_qname
402
+
403
+ # Avoid self-references
404
+ if child_qname != parent_qname
405
+ @inheritance_graph[parent_qname] ||= []
406
+ @inheritance_graph[parent_qname] << child_qname
407
+ end
408
+ end
409
+ end
410
+
411
+ # Extract parent name from generalization object
412
+ #
413
+ # @param generalization [Lutaml::Uml::Generalization]
414
+ # Generalization object
415
+ # @return [String, nil] Parent class name
416
+ def extract_parent_name(generalization) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
417
+ return nil unless generalization
418
+
419
+ # Check for general attribute (could be a string or object)
420
+ if generalization.respond_to?(:general)
421
+ parent = generalization.general
422
+ return parent.name if parent.respond_to?(:name)
423
+ return parent.to_s if parent
424
+ end
425
+
426
+ # Check for name attribute directly
427
+ if generalization.respond_to?(:name) && generalization.name
428
+ return generalization.name
429
+ end
430
+
431
+ nil
432
+ end
433
+
434
+ # Resolve a class name to its qualified name
435
+ #
436
+ # This is a simplified resolution that checks:
437
+ # 1. Same package
438
+ # 2. Already qualified name in index
439
+ #
440
+ # @param name [String] Class name to resolve
441
+ # @param current_package_path [String] Current package context
442
+ # @return [String, nil] Resolved qualified name
443
+ def resolve_qualified_name(name, current_package_path)
444
+ # If name contains "::", it might already be qualified
445
+ return name if @qualified_names.key?(name)
446
+
447
+ # Try in current package
448
+ local_qname = "#{current_package_path}::#{name}"
449
+ return local_qname if @qualified_names.key?(local_qname)
450
+
451
+ # Try to find in all qualified names (simple name match)
452
+ @qualified_names.each_key do |qname|
453
+ return qname if qname.end_with?("::#{name}")
454
+ end
455
+
456
+ nil
457
+ end
458
+ end
459
+ end
460
+ end
@@ -0,0 +1,238 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "repository"
4
+
5
+ module Lutaml
6
+ module UmlRepository
7
+ # LazyRepository provides lazy loading optimization for very large
8
+ # UML models
9
+ #
10
+ # For extremely large models (1000+ classes), LazyRepository optimizes
11
+ # memory usage and initial load time by building indexes on-demand rather
12
+ # than upfront. Indexes are built only when first accessed, reducing the
13
+ # initial load time significantly.
14
+ #
15
+ # @example Using lazy loading from XMI
16
+ # repo = Lutaml::Xmi::Repository.from_xmi_lazy('large-model.xmi')
17
+ # # Only metadata loaded at this point
18
+ #
19
+ # klass = repo.find_class("ModelRoot::MyClass")
20
+ # # Now qualified_names index is built
21
+ #
22
+ # @example Building all indexes manually
23
+ # repo = Lutaml::Xmi::Repository.from_xmi_lazy('model.xmi')
24
+ # repo.build_all_indexes
25
+ # # All indexes are now available
26
+ class LazyRepository < Repository
27
+ # Initialize a new LazyRepository with lazy index building.
28
+ #
29
+ # @param document [Lutaml::Uml::Document] The UML document to wrap
30
+ # @param indexes [Hash, nil] Pre-built indexes, or nil to build lazily
31
+ # @param lazy [Boolean] Whether to enable lazy loading (default: true)
32
+ # @return [LazyRepository] A new repository instance (not frozen)
33
+ def initialize(document:, indexes: nil, lazy: true) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
34
+ @document = document
35
+ @indexes = indexes || {}
36
+ @lazy_mode = lazy
37
+ @index_builders_pending = Set.new(%i[
38
+ package_paths
39
+ qualified_names
40
+ stereotypes
41
+ inheritance_graph
42
+ diagram_index
43
+ ])
44
+
45
+ # Initialize runtime query services (not serialized to LUR)
46
+ # These are lightweight wrappers that operate on @document and @indexes
47
+ @package_query = Queries::PackageQuery.new(@document, @indexes)
48
+ @class_query = Queries::ClassQuery.new(@document, @indexes)
49
+ @inheritance_query = Queries::InheritanceQuery.new(@document, @indexes)
50
+ @association_query = Queries::AssociationQuery.new(@document, @indexes)
51
+ @diagram_query = Queries::DiagramQuery.new(@document, @indexes)
52
+ @search_query = Queries::SearchQuery.new(@document, @indexes)
53
+
54
+ # Initialize statistics calculator (lazily computed)
55
+ @statistics_calculator = StatisticsCalculator.new(@document, @indexes)
56
+
57
+ # Initialize error handler for helpful error messages
58
+ @error_handler = ErrorHandler.new(self)
59
+
60
+ # Don't freeze - we build indexes on demand
61
+ end
62
+
63
+ # Find a class by its qualified name.
64
+ #
65
+ # Ensures the qualified_names index is built before querying.
66
+ #
67
+ # @param qualified_name [String] The qualified name
68
+ # @param raise_on_error [Boolean] Whether to raise an error if not found
69
+ # @return [Lutaml::Uml::Class, Lutaml::Uml::DataType,
70
+ # Lutaml::Uml::Enum, nil]
71
+ def find_class(qualified_name, raise_on_error: false)
72
+ ensure_index(:qualified_names)
73
+ super
74
+ end
75
+
76
+ # Find a package by its path.
77
+ #
78
+ # Ensures the package_paths index is built before querying.
79
+ #
80
+ # @param path [String] The package path
81
+ # @param raise_on_error [Boolean] Whether to raise an error if not found
82
+ # @return [Lutaml::Uml::Package, Lutaml::Uml::Document, nil]
83
+ def find_package(path, raise_on_error: false)
84
+ ensure_index(:package_paths)
85
+ super
86
+ end
87
+
88
+ # Find all classes with a specific stereotype.
89
+ #
90
+ # Ensures the stereotypes index is built before querying.
91
+ #
92
+ # @param stereotype [String] The stereotype to search for
93
+ # @return [Array] Array of class objects with the stereotype
94
+ def find_classes_by_stereotype(stereotype)
95
+ ensure_index(:stereotypes)
96
+ super
97
+ end
98
+
99
+ # Get the direct parent class (supertype).
100
+ #
101
+ # Ensures the qualified_names and inheritance_graph indexes are built.
102
+ #
103
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
104
+ # or qualified name string
105
+ # @return [Lutaml::Uml::Class, nil] The parent class, or nil if no parent
106
+ def supertype_of(class_or_qname)
107
+ ensure_index(:qualified_names)
108
+ ensure_index(:inheritance_graph)
109
+ super
110
+ end
111
+
112
+ # Get direct child classes (subtypes).
113
+ #
114
+ # Ensures the inheritance_graph index is built before querying.
115
+ #
116
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
117
+ # or qualified name string
118
+ # @param recursive [Boolean] Whether to include all descendants
119
+ # @return [Array] Array of child class objects
120
+ def subtypes_of(class_or_qname, recursive: false)
121
+ ensure_index(:inheritance_graph)
122
+ super
123
+ end
124
+
125
+ # Get all ancestor classes up to the root.
126
+ #
127
+ # Ensures the qualified_names and inheritance_graph indexes are built.
128
+ #
129
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
130
+ # or qualified name string
131
+ # @return [Array] Array of ancestor class objects
132
+ def ancestors_of(class_or_qname)
133
+ ensure_index(:qualified_names)
134
+ ensure_index(:inheritance_graph)
135
+ super
136
+ end
137
+
138
+ # Get all descendant classes.
139
+ #
140
+ # Ensures the inheritance_graph index is built before querying.
141
+ #
142
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
143
+ # or qualified name string
144
+ # @param max_depth [Integer, nil] Maximum depth to traverse
145
+ # @return [Array] Array of descendant class objects
146
+ def descendants_of(class_or_qname, max_depth: nil)
147
+ ensure_index(:inheritance_graph)
148
+ super
149
+ end
150
+
151
+ # Get diagrams in a specific package.
152
+ #
153
+ # Ensures the diagram_index is built before querying.
154
+ #
155
+ # @param package_path [String] The package path or package ID
156
+ # @return [Array<Lutaml::Uml::Diagram>] Array of diagram objects
157
+ def diagrams_in_package(package_path)
158
+ ensure_index(:diagram_index)
159
+ super
160
+ end
161
+
162
+ # Manually build all remaining indexes.
163
+ #
164
+ # This method can be called to force building all indexes at once,
165
+ # rather than waiting for them to be built on-demand.
166
+ #
167
+ # @return [LazyRepository] Returns self for method chaining
168
+ # @example
169
+ # repo = Repository.from_xmi_lazy('model.xmi')
170
+ # repo.build_all_indexes
171
+ # # All indexes are now built
172
+ def build_all_indexes
173
+ @index_builders_pending.each { |index_name| ensure_index(index_name) }
174
+ self
175
+ end
176
+
177
+ # Check if an index is built.
178
+ #
179
+ # @param index_name [Symbol] The name of the index to check
180
+ # @return [Boolean] True if the index is built, false otherwise
181
+ # @example
182
+ # repo.index_built?(:qualified_names) # => false
183
+ # repo.find_class("ModelRoot::MyClass")
184
+ # repo.index_built?(:qualified_names) # => true
185
+ def index_built?(index_name)
186
+ @indexes.key?(index_name) && !@indexes[index_name].nil?
187
+ end
188
+
189
+ # Get list of pending indexes.
190
+ #
191
+ # Returns the names of indexes that have not yet been built.
192
+ #
193
+ # @return [Array<Symbol>] Array of pending index names
194
+ # @example
195
+ # repo.pending_indexes # => [:package_paths, :qualified_names, ...]
196
+ def pending_indexes
197
+ @index_builders_pending.to_a
198
+ end
199
+
200
+ private
201
+
202
+ # Ensure an index is built.
203
+ #
204
+ # If the index is already built, this method returns immediately.
205
+ # Otherwise, it builds the index and removes it from the pending list.
206
+ #
207
+ # @param index_name [Symbol] The name of the index to ensure
208
+ # @return [void]
209
+ def ensure_index(index_name) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength
210
+ return if index_built?(index_name)
211
+
212
+ puts "Building #{index_name} index..." if $VERBOSE
213
+
214
+ case index_name
215
+ when :package_paths
216
+ @indexes[:package_paths] = IndexBuilder.build_package_paths(@document)
217
+ when :qualified_names
218
+ @indexes[:qualified_names] =
219
+ IndexBuilder.build_qualified_names(@document)
220
+ when :stereotypes
221
+ @indexes[:stereotypes] = IndexBuilder.build_stereotypes(@document)
222
+ when :inheritance_graph
223
+ # Requires qualified_names first
224
+ ensure_index(:qualified_names)
225
+ @indexes[:inheritance_graph] =
226
+ IndexBuilder.build_inheritance_graph(@document, @indexes)
227
+ when :diagram_index
228
+ # Requires package_paths first
229
+ ensure_index(:package_paths)
230
+ @indexes[:diagram_index] =
231
+ IndexBuilder.build_diagram_index(@document, @indexes)
232
+ end
233
+
234
+ @index_builders_pending.delete(index_name)
235
+ end
236
+ end
237
+ end
238
+ end