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,764 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../parser"
4
+ require_relative "../uml/package_path"
5
+ require_relative "../uml/qualified_name"
6
+ require_relative "error_handler"
7
+ require_relative "index_builder"
8
+ require_relative "statistics_calculator"
9
+ require_relative "validators/repository_validator"
10
+ require_relative "package_exporter"
11
+ require_relative "package_loader"
12
+ require_relative "package_metadata"
13
+ require_relative "queries/package_query"
14
+ require_relative "queries/class_query"
15
+ require_relative "queries/inheritance_query"
16
+ require_relative "queries/association_query"
17
+ require_relative "queries/diagram_query"
18
+ require_relative "queries/search_query"
19
+ require_relative "query_dsl/query_builder"
20
+ # require_relative "lazy_repository"
21
+
22
+ module Lutaml
23
+ module UmlRepository
24
+ # Repository provides a fully indexed, queryable in-memory representation
25
+ # of a UML model.
26
+ #
27
+ # It wraps the existing [`Lutaml::Uml::Document`](../../uml/document.rb)
28
+ # model and adds:
29
+ # - Package hierarchy with path-based navigation
30
+ # - Class index with qualified name lookups
31
+ # - Type resolution for attribute data types
32
+ # - Association tracking including ownership and navigability
33
+ # - Diagram metadata for visualization
34
+ # - Search capabilities across all model elements
35
+ #
36
+ # Repository can be built from XMI files or loaded from pre-serialized
37
+ # LUR (LutaML UML Repository) packages for instant loading.
38
+ #
39
+ # @example Building from XMI
40
+ # repo = Lutaml::Xmi::Repository.from_xmi('model.xmi')
41
+ # klass = repo.find_class("ModelRoot::i-UR::urf::Building")
42
+ #
43
+ # @example Navigating package hierarchy
44
+ # packages = repo.list_packages("ModelRoot::i-UR", recursive: true)
45
+ # tree = repo.package_tree("ModelRoot", max_depth: 2)
46
+ #
47
+ # @example Querying inheritance
48
+ # parent = repo.supertype_of("ModelRoot::Child")
49
+ # descendants = repo.descendants_of("ModelRoot::Parent", max_depth: 2)
50
+ class Repository
51
+ # @return [Lutaml::Uml::Document] The underlying UML document
52
+ attr_reader :document
53
+
54
+ # @return [Hash] The indexes for fast lookups
55
+ attr_reader :indexes
56
+
57
+ # @return [PackageMetadata, nil] The package metadata (if loaded from LUR)
58
+ attr_reader :metadata
59
+
60
+ # Initialize a new Repository.
61
+ #
62
+ # This is typically not called directly.
63
+ # Use [`from_xmi`](#from_xmi) instead.
64
+ #
65
+ # @param document [Lutaml::Uml::Document] The UML document to wrap
66
+ # @param indexes [Hash, nil] Pre-built indexes, or nil to build them
67
+ # automatically
68
+ # @param metadata [PackageMetadata, nil] Package metadata
69
+ # (if loaded from LUR)
70
+ # @return [Repository] A new frozen repository instance
71
+ # @example
72
+ # indexes = IndexBuilder.build_all(document)
73
+ # repo = Repository.new(document: document, indexes: indexes)
74
+ def initialize(document:, indexes: nil, metadata: nil, options: {}) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
75
+ @document = document.freeze
76
+ @indexes = indexes || IndexBuilder.build_all(document)
77
+ @metadata = metadata
78
+
79
+ # Initialize runtime query services (not serialized to LUR)
80
+ # These are lightweight wrappers that operate on @document and @indexes
81
+ unless options[:skip_queries]
82
+ @package_query = Queries::PackageQuery.new(@document, @indexes)
83
+ @class_query = Queries::ClassQuery.new(@document, @indexes)
84
+ @inheritance_query = Queries::InheritanceQuery.new(
85
+ @document, @indexes
86
+ )
87
+ @association_query = Queries::AssociationQuery.new(
88
+ @document, @indexes
89
+ )
90
+ @diagram_query = Queries::DiagramQuery.new(@document, @indexes)
91
+ @search_query = Queries::SearchQuery.new(@document, @indexes)
92
+ end
93
+
94
+ # Initialize statistics calculator and cache result
95
+ @statistics_calculator = StatisticsCalculator.new(@document, @indexes)
96
+ @statistics = @statistics_calculator.calculate.freeze
97
+
98
+ # Initialize error handler for helpful error messages
99
+ @error_handler = ErrorHandler.new(self)
100
+
101
+ freeze
102
+ end
103
+
104
+ # Build a Repository from an XMI file.
105
+ #
106
+ # @param xmi_path [String] Path to the XMI file
107
+ # @param options [Hash] Options for parsing
108
+ # @option options [Boolean] :validate (false) Validate model consistency
109
+ # after building indexes
110
+ # @return [Repository] A new repository instance
111
+ # @example
112
+ # repo = Repository.from_xmi('model.xmi')
113
+ # repo = Repository.from_xmi('model.xmi', validate: true)
114
+ def self.from_xmi(xmi_path, options = {})
115
+ # Parse XMI using Lutaml::Parser
116
+ document = Lutaml::Parser.parse([File.new(xmi_path)]).first
117
+
118
+ # Build indexes
119
+ indexes = IndexBuilder.build_all(document)
120
+
121
+ # Optionally validate (placeholder for future validation logic)
122
+ # if options[:validate]
123
+ # validate_model(document, indexes)
124
+ # end
125
+
126
+ new(document: document, indexes: indexes, options: options)
127
+ end
128
+
129
+ # Build a Repository from an XMI file with lazy index loading.
130
+ #
131
+ # This method creates a LazyRepository that builds indexes on-demand
132
+ # rather than upfront. Useful for very large models (1000+ classes)
133
+ # to reduce initial load time and memory usage.
134
+ #
135
+ # @param xmi_path [String] Path to the XMI file
136
+ # @param options [Hash] Options for parsing
137
+ # @return [LazyRepository] A new lazy repository instance
138
+ # @example
139
+ # repo = Repository.from_xmi_lazy('large-model.xmi')
140
+ # # Only document loaded, indexes built on first access
141
+ def self.from_xmi_lazy(xmi_path, _options = {})
142
+ # Parse XMI using Lutaml::Parser
143
+ document = Lutaml::Parser.parse([File.new(xmi_path)]).first
144
+
145
+ LazyRepository.new(document: document, lazy: true)
146
+ end
147
+
148
+ # Auto-detect file type and load appropriately.
149
+ #
150
+ # Detects whether the file is an XMI file (.xmi) or a LUR package (.lur)
151
+ # and loads it using the appropriate method.
152
+ #
153
+ # @param path [String] Path to the file (.xmi or .lur)
154
+ # @return [Repository] A new or loaded repository instance
155
+ # @raise [ArgumentError] If the file type is unknown
156
+ # @example
157
+ # repo = Repository.from_file('model.xmi')
158
+ # repo = Repository.from_file('model.lur')
159
+ def self.from_file(path)
160
+ case File.extname(path).downcase
161
+ when ".xmi" then from_xmi(path)
162
+ when ".lur" then from_package(path)
163
+ else
164
+ raise ArgumentError,
165
+ "Unknown file type: #{path}. Expected .xmi or .lur"
166
+ end
167
+ end
168
+
169
+ # Smart caching - use LUR if newer than XMI, otherwise rebuild.
170
+ #
171
+ # This method implements intelligent caching by checking if a LUR package
172
+ # exists and is newer than the source XMI file. If so, it loads from the
173
+ # cache. Otherwise, it builds from XMI and creates/updates the cache.
174
+ #
175
+ # @param xmi_path [String] Path to the XMI file
176
+ # @param lur_path [String, nil] Path to the LUR package (default: XMI path
177
+ # with .lur extension)
178
+ # @return [Repository] A repository instance
179
+ # @example Using default cache path
180
+ # repo = Repository.from_file_cached('model.xmi')
181
+ # # Creates/uses model.lur
182
+ #
183
+ # @example Using custom cache path
184
+ # repo = Repository.from_file_cached('model.xmi',
185
+ # lur_path: 'cache/model.lur')
186
+ def self.from_file_cached(xmi_path, lur_path: nil) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
187
+ lur_path ||= xmi_path.sub(/\.xmi$/i, ".lur")
188
+
189
+ if File.exist?(lur_path) && File.mtime(lur_path) >= File.mtime(xmi_path)
190
+ puts "Using cached LUR package: #{lur_path}" if $VERBOSE
191
+ from_package(lur_path)
192
+ else
193
+ puts "Building repository from XMI..." if $VERBOSE
194
+ repo = from_xmi(xmi_path)
195
+
196
+ puts "Caching as LUR package: #{lur_path}" if $VERBOSE
197
+ repo.export_to_package(lur_path)
198
+ repo
199
+ end
200
+ end
201
+
202
+ # Load a Repository from a LUR package file.
203
+ #
204
+ # @param lur_path [String] Path to the .lur package file
205
+ # @return [Repository] A loaded repository instance
206
+ # @example
207
+ # repo = Repository.from_package("model.lur")
208
+ def self.from_package(lur_path)
209
+ PackageLoader.load(lur_path)
210
+ end
211
+
212
+ # Load a Repository from a LUR package file with lazy loading.
213
+ #
214
+ # This method loads the document without building indexes, deferring
215
+ # index creation until first access. Useful for very large models.
216
+ #
217
+ # @param lur_path [String] Path to the .lur package file
218
+ # @return [LazyRepository] A loaded lazy repository instance
219
+ # @example
220
+ # repo = Repository.from_package_lazy("large-model.lur")
221
+ def self.from_package_lazy(lur_path)
222
+ PackageLoader.load_document_only(lur_path)
223
+ end
224
+
225
+ # Auto-detect file type and load with lazy loading.
226
+ #
227
+ # Detects whether the file is an XMI file (.xmi) or a LUR package (.lur)
228
+ # and loads it using the appropriate lazy loading method.
229
+ #
230
+ # @param path [String] Path to the file (.xmi or .lur)
231
+ # @return [LazyRepository] A new or loaded lazy repository instance
232
+ # @raise [ArgumentError] If the file type is unknown
233
+ # @example
234
+ # repo = Repository.from_file_lazy('large-model.xmi')
235
+ # repo = Repository.from_file_lazy('large-model.lur')
236
+ def self.from_file_lazy(path)
237
+ case File.extname(path).downcase
238
+ when ".xmi" then from_xmi_lazy(path)
239
+ when ".lur" then from_package_lazy(path)
240
+ else
241
+ raise ArgumentError,
242
+ "Unknown file type: #{path}. Expected .xmi or .lur"
243
+ end
244
+ end
245
+
246
+ # Export this repository to a LUR package file.
247
+ #
248
+ # @param output_path [String] Path for the output .lur file
249
+ # @param options [Hash] Export options
250
+ # @option options [PackageMetadata, Hash] :metadata Package metadata
251
+ # @option options [String] :name ("UML Model") Package name
252
+ # (deprecated, use :metadata)
253
+ # @option options [String] :version ("1.0") Package version
254
+ # (deprecated, use :metadata)
255
+ # @option options [Boolean] :include_xmi (false) Include source XMI
256
+ # @option options [Symbol] :serialization_format (:marshal) Format to use
257
+ # (:marshal or :yaml)
258
+ # @option options [Integer] :compression_level (6) ZIP compression level
259
+ # @return [void]
260
+ # @example Export with defaults
261
+ # repo.export_to_package("model.lur")
262
+ #
263
+ # @example Export with PackageMetadata
264
+ # metadata = PackageMetadata.new(
265
+ # name: "Urban Model",
266
+ # version: "2.0",
267
+ # publisher: "City Planning"
268
+ # )
269
+ # repo.export_to_package("model.lur", metadata: metadata)
270
+ #
271
+ # @example Export with custom options (backward compatible)
272
+ # repo.export_to_package("model.lur",
273
+ # name: "My Model",
274
+ # version: "2.0",
275
+ # serialization_format: :yaml
276
+ # )
277
+ def export_to_package(output_path, options = {})
278
+ PackageExporter.new(self, options).export(output_path)
279
+ end
280
+
281
+ # Find a package by its path.
282
+ #
283
+ # @param path [String] The package path (e.g., "ModelRoot::i-UR::urf")
284
+ # @param raise_on_error [Boolean] Whether to raise an error if not found
285
+ # (default: false)
286
+ # @return [Lutaml::Uml::Package, Lutaml::Uml::Document, nil] The package
287
+ # or document, or nil if not found
288
+ # @raise [NameError] If package not found and raise_on_error is true
289
+ # @example
290
+ # package = repo.find_package("ModelRoot::i-UR::urf")
291
+ # package = repo.find_package("ModelRoot::typo", raise_on_error: true)
292
+ def find_package(path, raise_on_error: false)
293
+ result = package_query.find_by_path(path)
294
+ return result if result || !raise_on_error
295
+
296
+ @error_handler.package_not_found_error(path)
297
+ end
298
+
299
+ # List packages at a specific path.
300
+ #
301
+ # @param path [String] The parent package path (default: "ModelRoot")
302
+ # @param recursive [Boolean] Whether to include nested packages
303
+ # recursively (default: false)
304
+ # @return [Array<Lutaml::Uml::Package>] Array of packages
305
+ # @example Non-recursive listing
306
+ # packages = repo.list_packages("ModelRoot::i-UR", recursive: false)
307
+ #
308
+ # @example Recursive listing
309
+ # packages = repo.list_packages("ModelRoot", recursive: true)
310
+ def list_packages(path = "ModelRoot", recursive: false)
311
+ package_query.list(path, recursive: recursive)
312
+ end
313
+
314
+ # Build a hierarchical tree structure of packages.
315
+ #
316
+ # @param path [String] The root package path to start from
317
+ # (default: "ModelRoot")
318
+ # @param max_depth [Integer, nil] Maximum depth to traverse (nil for
319
+ # unlimited)
320
+ # @return [Hash, nil] Tree structure with package information, or nil
321
+ # if root not found
322
+ # @example
323
+ # tree = repo.package_tree("ModelRoot::i-UR", max_depth: 2)
324
+ def package_tree(path = "ModelRoot", max_depth: nil)
325
+ package_query.tree(path, max_depth: max_depth)
326
+ end
327
+
328
+ # Find a class by its qualified name.
329
+ #
330
+ # @param qualified_name [String] The qualified name
331
+ # (e.g., "ModelRoot::i-UR::urf::Building")
332
+ # @param raise_on_error [Boolean] Whether to raise an error if not found
333
+ # (default: false)
334
+ # @return [Lutaml::Uml::Class, Lutaml::Uml::DataType,
335
+ # Lutaml::Uml::Enum, nil]
336
+ # The class object, or nil if not found
337
+ # @raise [NameError] If class not found and raise_on_error is true
338
+ # @example
339
+ # klass = repo.find_class("ModelRoot::i-UR::urf::Building")
340
+ # klass = repo.find_class("ModelRoot::Typo", raise_on_error: true)
341
+ def find_class(qualified_name, raise_on_error: false)
342
+ result = class_query.find_by_qname(qualified_name)
343
+ return result if result || !raise_on_error
344
+
345
+ @error_handler.class_not_found_error(qualified_name)
346
+ end
347
+
348
+ # Find all classes with a specific stereotype.
349
+ #
350
+ # @param stereotype [String] The stereotype to search for
351
+ # @return [Array] Array of class objects with the stereotype
352
+ # @example
353
+ # feature_types = repo.find_classes_by_stereotype("featureType")
354
+ def find_classes_by_stereotype(stereotype)
355
+ class_query.find_by_stereotype(stereotype)
356
+ end
357
+
358
+ # Get classes in a specific package.
359
+ #
360
+ # @param package_path [String] The package path
361
+ # @param recursive [Boolean] Whether to include classes from nested
362
+ # packages (default: false)
363
+ # @return [Array] Array of class objects in the package
364
+ # @example
365
+ # classes = repo.classes_in_package("ModelRoot::i-UR::urf")
366
+ # all_classes = repo.classes_in_package(
367
+ # "ModelRoot::i-UR", recursive: true)
368
+ def classes_in_package(package_path, recursive: false)
369
+ class_query.in_package(package_path, recursive: recursive)
370
+ end
371
+
372
+ # Get the direct parent class (supertype).
373
+ #
374
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
375
+ # or qualified name string
376
+ # @return [Lutaml::Uml::Class, nil] The parent class, or nil if no parent
377
+ # @example
378
+ # parent = repo.supertype_of("ModelRoot::Child")
379
+ # parent = repo.supertype_of(child_class)
380
+ def supertype_of(class_or_qname)
381
+ inheritance_query.supertype(class_or_qname)
382
+ end
383
+
384
+ # Get direct child classes (subtypes).
385
+ #
386
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
387
+ # or qualified name string
388
+ # @param recursive [Boolean] Whether to include all descendants
389
+ # (default: false)
390
+ # @return [Array] Array of child class objects
391
+ # @example
392
+ # children = repo.subtypes_of("ModelRoot::Parent")
393
+ # all_descendants = repo.subtypes_of(
394
+ # "ModelRoot::Parent", recursive: true)
395
+ def subtypes_of(class_or_qname, recursive: false)
396
+ inheritance_query.subtypes(class_or_qname, recursive: recursive)
397
+ end
398
+
399
+ # Get all ancestor classes up to the root.
400
+ #
401
+ # Returns ancestors in order from immediate parent to root.
402
+ #
403
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
404
+ # or qualified name string
405
+ # @return [Array] Array of ancestor class objects, ordered from nearest
406
+ # to furthest
407
+ # @example
408
+ # ancestors = repo.ancestors_of("ModelRoot::GrandChild")
409
+ def ancestors_of(class_or_qname)
410
+ inheritance_query.ancestors(class_or_qname)
411
+ end
412
+
413
+ # Get all descendant classes.
414
+ #
415
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
416
+ # or qualified name string
417
+ # @param max_depth [Integer, nil] Maximum depth to traverse (nil for
418
+ # unlimited)
419
+ # @return [Array] Array of descendant class objects
420
+ # @example
421
+ # descendants = repo.descendants_of("ModelRoot::Parent", max_depth: 2)
422
+ def descendants_of(class_or_qname, max_depth: nil)
423
+ inheritance_query.descendants(class_or_qname, max_depth: max_depth)
424
+ end
425
+
426
+ # Get associations involving a class.
427
+ #
428
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
429
+ # or qualified name string
430
+ # @param options [Hash] Query options
431
+ # @option options [Symbol] :direction (:both) Filter by direction:
432
+ # :source, :target, or :both
433
+ # @option options [Boolean] :owned_only Return only owned associations
434
+ # @option options [Boolean] :navigable_only
435
+ # Return only navigable associations
436
+ # @return [Array<Lutaml::Uml::Association>] Array of association objects
437
+ # @example
438
+ # all_assocs = repo.associations_of("ModelRoot::Building")
439
+ # outgoing = repo.associations_of(
440
+ # "ModelRoot::Building", direction: :source)
441
+ def associations_of(class_or_qname, options = {})
442
+ association_query.find_for_class(class_or_qname, options)
443
+ end
444
+
445
+ # Get diagrams in a specific package.
446
+ #
447
+ # @param package_path [String] The package path or package ID
448
+ # @return [Array<Lutaml::Uml::Diagram>] Array of diagram objects
449
+ # @example
450
+ # diagrams = repo.diagrams_in_package("ModelRoot::i-UR::urf")
451
+ def diagrams_in_package(package_path)
452
+ diagram_query.in_package(package_path)
453
+ end
454
+
455
+ # Find a diagram by its name.
456
+ #
457
+ # @param diagram_name [String] The diagram name
458
+ # @return [Lutaml::Uml::Diagram, nil] The diagram object,
459
+ # or nil if not found
460
+ # @example
461
+ # diagram = repo.find_diagram("Class Diagram 1")
462
+ def find_diagram(diagram_name)
463
+ diagram_query.find_by_name(diagram_name)
464
+ end
465
+
466
+ # Get all diagrams in the model.
467
+ #
468
+ # @return [Array<Lutaml::Uml::Diagram>] Array of all diagram objects
469
+ # @example
470
+ # all_diagrams = repo.all_diagrams
471
+ def all_diagrams
472
+ diagram_query.all
473
+ end
474
+
475
+ # Search for model elements by query string.
476
+ #
477
+ # @param query [String] The search query
478
+ # @param types [Array<Symbol>] Types to search (:class, :attribute,
479
+ # :association) (default: [:class, :attribute, :association])
480
+ # @param fields [Array<Symbol>] Fields to search in
481
+ # (:name, :documentation)
482
+ # (default: [:name])
483
+ # @return [Hash] Search results grouped by type
484
+ # @example
485
+ # results = repo.search("Building")
486
+ # results = repo.search("address", types: [:attribute])
487
+ # results = repo.search("urban", fields: [:name, :documentation])
488
+ def search(
489
+ query, types: %i[class attribute association], fields: [:name]
490
+ )
491
+ search_query.search(query, types: types, fields: fields)
492
+ end
493
+
494
+ # Search for model elements by regex pattern.
495
+ #
496
+ # Similar to search but treats query as a regex pattern. Returns
497
+ # SearchResult objects for consistency with regular search.
498
+ #
499
+ # @param pattern [String, Regexp] The regex pattern to match
500
+ # @param types [Array<Symbol>] Types to search (:class, :attribute,
501
+ # :association) (default: [:class, :attribute, :association])
502
+ # @param fields [Array<Symbol>] Fields to search in
503
+ # (:name, :documentation)
504
+ # (default: [:name])
505
+ # @return [Hash] Search results grouped by type (same format as search)
506
+ # @example
507
+ # results = repo.search("^Building.*", types:[:class])
508
+ # results = repo.search("address$", types: [:attribute])
509
+ # results = repo.search("urban", fields: [:documentation])
510
+ def search( # rubocop:disable Lint/DuplicateMethods
511
+ pattern,
512
+ types: %i[class attribute association],
513
+ fields: [:name]
514
+ )
515
+ search_query.search(pattern, types: types, fields: fields)
516
+ end
517
+
518
+ # Get comprehensive statistics about the repository.
519
+ #
520
+ # Returns detailed metrics including package depths, class complexity,
521
+ # attribute distributions, and model quality metrics.
522
+ # Statistics are calculated once during initialization and cached.
523
+ #
524
+ # @return [Hash] Comprehensive statistics hash
525
+ # @example
526
+ # stats = repo.statistics
527
+ # puts "Total packages: #{stats[:total_packages]}"
528
+ # puts "Max package depth: #{stats[:max_package_depth]}"
529
+ # puts "Most complex class:
530
+ # #{stats[:most_complex_classes].first[:name]}"
531
+ def statistics
532
+ @statistics
533
+ end
534
+
535
+ # Validate the repository for consistency and integrity.
536
+ #
537
+ # Performs comprehensive validation including:
538
+ # - Type reference validation
539
+ # - Generalization reference validation
540
+ # - Circular inheritance detection
541
+ # - Association reference validation
542
+ # - Multiplicity validation
543
+ #
544
+ # @param verbose [Boolean] Collect detailed validation information
545
+ # @return [Validators::ValidationResult] Validation results
546
+ # @example
547
+ # result = repo.validate
548
+ # if result.valid?
549
+ # puts "Repository is valid"
550
+ # else
551
+ # result.errors.each { |error| puts "ERROR: #{error}" }
552
+ # end
553
+ def validate(verbose: false)
554
+ Validators::RepositoryValidator.new(@document,
555
+ @indexes).validate(verbose: verbose)
556
+ end
557
+
558
+ # Build a query using the Query DSL
559
+ #
560
+ # Provides a fluent interface for building complex queries with
561
+ # method chaining, lazy evaluation, and composable filters.
562
+ #
563
+ # @yield [QueryDSL::QueryBuilder] The query builder
564
+ # @return [QueryDSL::QueryBuilder] The query builder for further chaining
565
+ # @example Basic query
566
+ # results = repo.query do |q|
567
+ # q.classes.where(stereotype: 'featureType')
568
+ # end.all
569
+ #
570
+ # @example Complex query
571
+ # results = repo.query do |q|
572
+ # q.classes
573
+ # .in_package('ModelRoot::i-UR', recursive: true)
574
+ # .where { |c| c.attributes&.size.to_i > 10 }
575
+ # .order_by(:name, direction: :desc)
576
+ # .limit(5)
577
+ # end.execute
578
+ def query(&block)
579
+ builder = QueryDSL::QueryBuilder.new(self)
580
+ block&.call(builder)
581
+ builder
582
+ end
583
+
584
+ # Build and execute a query using the Query DSL
585
+ #
586
+ # Same as [`query`](#query) but executes immediately and returns results.
587
+ #
588
+ # @yield [QueryDSL::QueryBuilder] The query builder
589
+ # @return [Array] The query results
590
+ # @example
591
+ # results = repo.query! do |q|
592
+ # q.classes.where(stereotype: 'featureType')
593
+ # end
594
+ def query!(&block)
595
+ query(&block).execute
596
+ end
597
+
598
+ # Convenience methods for SPA data transformer
599
+
600
+ # Get all packages as an array (excluding root Document)
601
+ # @return [Array<Lutaml::Uml::Package>] All packages
602
+ def packages_index
603
+ (@indexes[:package_paths]&.values || []).grep(Lutaml::Uml::Package)
604
+ end
605
+
606
+ # Get all classes (including datatypes and enums) as an array
607
+ # @return [Array] All classifiers
608
+ def classes_index
609
+ @indexes[:qualified_names]&.values || []
610
+ end
611
+
612
+ # Get all associations as an array
613
+ # Collects from both document-level (XMI) and class-level (QEA/EA)
614
+ # @return [Array<Lutaml::Uml::Association>] All associations
615
+ def associations_index # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
616
+ # Use cached index if available (built by IndexBuilder)
617
+ return @indexes[:associations].values if @indexes[:associations]
618
+
619
+ # Fallback for edge cases: collect from document and classes
620
+ associations = []
621
+
622
+ # Document-level associations (XMI format)
623
+ associations.concat(@document.associations) if @document.associations
624
+
625
+ # Class-level associations (QEA/EA format)
626
+ classes_index.each do |klass|
627
+ next unless klass.respond_to?(:associations) && klass.associations
628
+
629
+ klass.associations.each do |assoc|
630
+ # Avoid duplicates - check xmi_id
631
+ next if associations.any? { |a| a.xmi_id == assoc.xmi_id }
632
+
633
+ associations << assoc
634
+ end
635
+ end
636
+
637
+ associations
638
+ end
639
+
640
+ # Get qualified name(key) by the object from @indexes[:qualified_names]
641
+ def qualified_name_for(obj)
642
+ @indexes[:qualified_names].key(obj)
643
+ end
644
+
645
+ # Get all diagrams as an array
646
+ # @return [Array<Lutaml::Uml::Diagram>] All diagrams
647
+ def diagrams_index
648
+ all_diagrams
649
+ end
650
+
651
+ # Get all classes in the repository
652
+ # @return [Array] All class objects (classes, datatypes, enums)
653
+ # @example
654
+ # all = repo.all_classes
655
+ def all_classes
656
+ classes_index
657
+ end
658
+
659
+ # DEPRECATED: Use search with types: [:class] instead
660
+ # @deprecated Use {#search} with types filter
661
+ def search_classes(query_string)
662
+ search(query_string, types: [:class])[:classes]
663
+ end
664
+
665
+ # DEPRECATED: Use subtypes_of instead
666
+ # @deprecated Use {#subtypes_of}
667
+ def find_children(class_or_qname, recursive: false)
668
+ subtypes_of(class_or_qname, recursive: recursive)
669
+ end
670
+
671
+ # DEPRECATED: Use associations_of instead
672
+ # @deprecated Use {#associations_of}
673
+ def find_associations(class_or_qname, options = {})
674
+ associations_of(class_or_qname, options)
675
+ end
676
+
677
+ # DEPRECATED: Use diagrams_in_package or all_diagrams instead
678
+ # @deprecated Use {#diagrams_in_package} or {#all_diagrams}
679
+ def find_diagrams(package_path)
680
+ diagrams_in_package(package_path)
681
+ end
682
+
683
+ # DEPRECATED: Use export_to_package instead
684
+ # @deprecated Use {#export_to_package}
685
+ def export(output_path, options = {})
686
+ export_to_package(output_path, options)
687
+ end
688
+
689
+ # Custom marshaling to exclude runtime-only query objects
690
+ #
691
+ # Only serializes the core data (document, indexes, and metadata), not the
692
+ # derived query service objects. This keeps serialized size minimal.
693
+ #
694
+ # @return [Hash] Serializable state (document, indexes, and metadata)
695
+ # @api private
696
+ def marshal_dump
697
+ { document: @document, indexes: @indexes, metadata: @metadata }
698
+ end
699
+
700
+ # Restore from marshaled state
701
+ #
702
+ # Reconstructs the repository from serialized document, indexes,
703
+ # and metadata,
704
+ # reinitializing all query services.
705
+ #
706
+ # @param data [Hash] Serialized state with :document, :indexes,
707
+ # and :metadata
708
+ # @return [void]
709
+ # @api private
710
+ def marshal_load(data) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
711
+ @document = data[:document]
712
+ @indexes = data[:indexes]
713
+ @metadata = data[:metadata]
714
+
715
+ # Reinitialize runtime query services
716
+ @package_query = Queries::PackageQuery.new(@document, @indexes)
717
+ @class_query = Queries::ClassQuery.new(@document, @indexes)
718
+ @inheritance_query = Queries::InheritanceQuery.new(@document, @indexes)
719
+ @association_query = Queries::AssociationQuery.new(@document, @indexes)
720
+ @diagram_query = Queries::DiagramQuery.new(@document, @indexes)
721
+ @search_query = Queries::SearchQuery.new(@document, @indexes)
722
+
723
+ # Reinitialize helpers and cache statistics
724
+ @statistics_calculator = StatisticsCalculator.new(@document, @indexes)
725
+ @statistics = @statistics_calculator.calculate.freeze
726
+ @error_handler = ErrorHandler.new(self)
727
+
728
+ freeze
729
+ end
730
+
731
+ private
732
+
733
+ # Get package query service
734
+ #
735
+ # @return [Queries::PackageQuery] The package query service
736
+ attr_reader :package_query
737
+
738
+ # Get class query service
739
+ #
740
+ # @return [Queries::ClassQuery] The class query service
741
+ attr_reader :class_query
742
+
743
+ # Get inheritance query service
744
+ #
745
+ # @return [Queries::InheritanceQuery] The inheritance query service
746
+ attr_reader :inheritance_query
747
+
748
+ # Get association query service
749
+ #
750
+ # @return [Queries::AssociationQuery] The association query service
751
+ attr_reader :association_query
752
+
753
+ # Get diagram query service
754
+ #
755
+ # @return [Queries::DiagramQuery] The diagram query service
756
+ attr_reader :diagram_query
757
+
758
+ # Get search query service
759
+ #
760
+ # @return [Queries::SearchQuery] The search query service
761
+ attr_reader :search_query
762
+ end
763
+ end
764
+ end