lutaml 0.9.43 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +63 -0
  3. data/.github/workflows/links.yml +99 -0
  4. data/.github/workflows/rake.yml +13 -2
  5. data/.github/workflows/release.yml +12 -6
  6. data/.gitignore +3 -0
  7. data/.rubocop.yml +11 -3
  8. data/.rubocop_todo.yml +378 -0
  9. data/Gemfile +15 -7
  10. data/README.adoc +1854 -21
  11. data/Rakefile +7 -1
  12. data/TODO.bugfix.md +24 -0
  13. data/bin/plantuml2lutaml +3 -3
  14. data/bin/yaml2lutaml +2 -2
  15. data/config/diagram_styles.yml +200 -0
  16. data/config/model_transformations.yml +266 -0
  17. data/config/package_metadata.example.yml +58 -0
  18. data/config/qea_schema.yml +1024 -0
  19. data/config/static_site.yml +166 -0
  20. data/docs/.github/workflows/docs.yml +66 -0
  21. data/docs/.github/workflows/links.yml +78 -0
  22. data/docs/CONTINUATION_PLAN.md +168 -0
  23. data/docs/Gemfile +13 -0
  24. data/docs/MIGRATION_GUIDE.md +202 -0
  25. data/docs/README.md +252 -0
  26. data/docs/REFACTOR_PLAN.md +214 -0
  27. data/docs/_config.yml +144 -0
  28. data/docs/_guides/diagram-generation.adoc +316 -0
  29. data/docs/_guides/index.adoc +135 -0
  30. data/docs/{lutaml-express.adoc → _guides/parsing/express-parsing.adoc} +7 -0
  31. data/docs/_guides/parsing/index.adoc +77 -0
  32. data/docs/{lutaml-xmi.adoc → _guides/parsing/xmi-parsing.adoc} +7 -0
  33. data/docs/_guides/sysml-modeling.adoc +37 -0
  34. data/docs/{lutaml-uml.adoc → _guides/uml-modeling.adoc} +8 -2
  35. data/docs/_pages/concepts/diagram-generation.adoc +337 -0
  36. data/docs/_pages/concepts/lur-format.adoc +711 -0
  37. data/docs/_pages/concepts/qea-parsing.adoc +418 -0
  38. data/docs/_pages/core/architecture.adoc +329 -0
  39. data/docs/_pages/core/installation.adoc +321 -0
  40. data/docs/_pages/core/overview.adoc +197 -0
  41. data/docs/_pages/index.adoc +48 -0
  42. data/docs/_pages/uml-syntax.adoc +995 -0
  43. data/docs/_references/configuration/diagram-styles.adoc +716 -0
  44. data/docs/_references/configuration/index.adoc +52 -0
  45. data/docs/_references/configuration/package-metadata.adoc +416 -0
  46. data/docs/_references/formats/index.adoc +42 -0
  47. data/docs/{lutaml_syntax.adoc → _references/formats/lutaml-syntax.adoc} +7 -0
  48. data/docs/_references/formats/qea-structure.adoc +1364 -0
  49. data/docs/_references/index.adoc +197 -0
  50. data/docs/_tutorials/index.adoc +109 -0
  51. data/docs/index.adoc +64 -0
  52. data/docs/lychee.toml +83 -0
  53. data/examples/UML_EA.DTD +6856 -0
  54. data/examples/lur/20251010_current_plateau_v5.1.lur +0 -0
  55. data/examples/lur/basic.lur +0 -0
  56. data/examples/lur/test-output.lur +0 -0
  57. data/examples/lur/test.lur +0 -0
  58. data/examples/lur_basic_usage.rb +220 -0
  59. data/examples/lur_cli_workflow.rb +262 -0
  60. data/examples/lur_statistics.rb +325 -0
  61. data/examples/qea/20251010_current_plateau_v5.1.qea +0 -0
  62. data/examples/qea/ArcGISWorkspace_template.qea +0 -0
  63. data/examples/qea/README_qea_parser.adoc +230 -0
  64. data/examples/qea/UmlModel_template.qea +0 -0
  65. data/examples/qea/basic.qea +0 -0
  66. data/examples/qea/simple.qea +0 -0
  67. data/examples/qea/simple_example.qea +0 -0
  68. data/examples/qea/test.qea +0 -0
  69. data/examples/xmi/20251010_current_plateau_v5.1.xmi +118121 -0
  70. data/examples/xmi/ArcGISWorkspace_template.xmi +1467 -0
  71. data/examples/xmi/Images/EAID_0016F797_D055_4717_AF1A_606413D0A166.svg +158 -0
  72. data/examples/xmi/Images/EAID_00C5C772_5A03_434f_BF30_AC37542A1AAC.svg +659 -0
  73. data/examples/xmi/Images/EAID_0114FD24_9E58_4664_98CD_71305B59AD11.svg +411 -0
  74. data/examples/xmi/Images/EAID_01661E1B_31B6_4167_BCCF_A00678FB4EA2.svg +102 -0
  75. data/examples/xmi/Images/EAID_039FE004_5408_4fc0_89AA_EB319E4F61C7.svg +169 -0
  76. data/examples/xmi/Images/EAID_04EE9625_17A0_4721_BC71_21756DB21D06.svg +403 -0
  77. data/examples/xmi/Images/EAID_05FF9417_1619_4170_B0C9_55AA6B988EF1.svg +175 -0
  78. data/examples/xmi/Images/EAID_09853FB2_AF8A_432f_94C5_6C47461BD937.svg +360 -0
  79. data/examples/xmi/Images/EAID_09927B7F_A657_4819_99E5_AC9DC99227D9.svg +195 -0
  80. data/examples/xmi/Images/EAID_09AF6B8A_557C_43bc_BBB0_47C1E9401EF3.svg +218 -0
  81. data/examples/xmi/Images/EAID_0BE81AC5_031B_4973_A9A0_223CCD92BAA1.svg +471 -0
  82. data/examples/xmi/Images/EAID_0EDEA6EF_4DC8_4979_BB80_28B1B9EBD1D4.svg +56 -0
  83. data/examples/xmi/Images/EAID_0F413534_6AD2_48bc_B4AF_8699D530D91D.svg +262 -0
  84. data/examples/xmi/Images/EAID_1321F39B_AD67_47b5_B5C3_3A42BBFCBDF9.svg +286 -0
  85. data/examples/xmi/Images/EAID_13E09C71_99E7_40b4_B72D_48AF6379BC2E.svg +164 -0
  86. data/examples/xmi/Images/EAID_144955D8_CB4E_4b59_BB0C_E549F7F84943.svg +66 -0
  87. data/examples/xmi/Images/EAID_14E9F5FD_F6CD_4f48_B1CD_F5A40C6D8E83.svg +95 -0
  88. data/examples/xmi/Images/EAID_157826AA_96A7_4278_89A6_94BD0F31409A.svg +63 -0
  89. data/examples/xmi/Images/EAID_159E9DA0_7A54_4817_B72A_401C750F675D.svg +306 -0
  90. data/examples/xmi/Images/EAID_17BC8309_8051_492b_BE87_61CCFE83DB16.svg +45 -0
  91. data/examples/xmi/Images/EAID_1A10EB6D_E2E5_42a6_A31E_B293D93FD07E.svg +193 -0
  92. data/examples/xmi/Images/EAID_1A290AFD_CE96_46a2_8351_A986D77CC727.svg +444 -0
  93. data/examples/xmi/Images/EAID_1B2D9309_C66B_492a_995C_95B2B02E0D7C.svg +168 -0
  94. data/examples/xmi/Images/EAID_1DE6B973_CE8A_416f_909B_54CEA1E5944E.svg +10 -0
  95. data/examples/xmi/Images/EAID_204F4ACC_2230_4c8d_9861_EF5A6844B712.svg +60 -0
  96. data/examples/xmi/Images/EAID_227300E2_4F4B_4955_83B9_FA626CE8680B.svg +188 -0
  97. data/examples/xmi/Images/EAID_22C24D4C_4894_480a_B113_0CB034CB59E9.svg +426 -0
  98. data/examples/xmi/Images/EAID_234BC4F5_8100_4969_BDCB_A24E0E641F23.svg +169 -0
  99. data/examples/xmi/Images/EAID_24446BFC_9FEB_4935_8970_65A4C562A93F.svg +277 -0
  100. data/examples/xmi/Images/EAID_24E8A45C_C99F_49b7_860A_9CF65FF76C76.svg +575 -0
  101. data/examples/xmi/Images/EAID_272F3181_4300_48b7_98A0_A8CFD12B1A72.svg +255 -0
  102. data/examples/xmi/Images/EAID_292E0D94_392C_4da6_A0B5_841501FAE50A.svg +183 -0
  103. data/examples/xmi/Images/EAID_29DD0967_ADAB_4abb_99C5_544821F5E7DA.svg +10 -0
  104. data/examples/xmi/Images/EAID_2A339928_E5EF_4ed2_9E5D_CC2CA5CF248B.svg +310 -0
  105. data/examples/xmi/Images/EAID_2A5E0832_06BE_4381_85D4_9B00E4F95575.svg +155 -0
  106. data/examples/xmi/Images/EAID_2AAB709F_EFCE_496f_8AFE_92809D66A0A9.svg +81 -0
  107. data/examples/xmi/Images/EAID_2C8DD882_8DEA_4065_89F8_DDA796AA0C85.svg +520 -0
  108. data/examples/xmi/Images/EAID_2E98EA19_37D8_4b70_BDCE_CFEE4FA800B0.svg +173 -0
  109. data/examples/xmi/Images/EAID_30D62231_110F_44e8_9C06_6FCDCBA53A09.svg +722 -0
  110. data/examples/xmi/Images/EAID_3206D3FD_1FC4_41c7_8D00_36DB908E9319.svg +181 -0
  111. data/examples/xmi/Images/EAID_3452CC53_9ACB_44eb_9C9D_B90CF862F284.svg +92 -0
  112. data/examples/xmi/Images/EAID_348EE46E_ABD9_40b0_82A1_0285E75BDC52.svg +187 -0
  113. data/examples/xmi/Images/EAID_34FF671B_CFDC_47ad_91DF_ECA6D8358180.svg +217 -0
  114. data/examples/xmi/Images/EAID_359DD694_0100_4bdf_AD5F_712D97E9C69B.svg +157 -0
  115. data/examples/xmi/Images/EAID_35DE714C_49A8_490e_913A_56F39EF317F9.svg +180 -0
  116. data/examples/xmi/Images/EAID_360C79F1_8EDF_41db_A069_DECDC55625BC.svg +31 -0
  117. data/examples/xmi/Images/EAID_36913C58_FF35_4ba2_A04B_9A4824E24609.svg +166 -0
  118. data/examples/xmi/Images/EAID_372F7F7B_57ED_469a_A640_70DB578B3C56.svg +361 -0
  119. data/examples/xmi/Images/EAID_37AC19B9_8433_4fee_A326_763170D54D06.svg +32 -0
  120. data/examples/xmi/Images/EAID_38170608_32B5_4a6f_A68D_A0D7C0C9D019.svg +234 -0
  121. data/examples/xmi/Images/EAID_3A77A5D0_4E1B_4116_8AAD_407FC422B47F.svg +183 -0
  122. data/examples/xmi/Images/EAID_3B8BD087_1683_46b1_8D0D_6F839C46C578.svg +42 -0
  123. data/examples/xmi/Images/EAID_3DC20801_AE8B_4e76_B08C_F574E8A90E13.svg +192 -0
  124. data/examples/xmi/Images/EAID_3DE28C70_C6D4_406c_B49F_EEF52148C8C1.svg +124 -0
  125. data/examples/xmi/Images/EAID_458E093C_BA2B_4292_BEC4_37511C163DDC.svg +140 -0
  126. data/examples/xmi/Images/EAID_45F9B1F7_E568_47c9_B229_953BC2E707E4.svg +266 -0
  127. data/examples/xmi/Images/EAID_46B3041A_8C23_46e6_8E14_ADE7012274C5.svg +80 -0
  128. data/examples/xmi/Images/EAID_47E4600F_CEC9_4245_9BF5_EE38007A9DDB.svg +584 -0
  129. data/examples/xmi/Images/EAID_4881CEEE_792C_4cb0_BEA7_54333B643D0A.svg +155 -0
  130. data/examples/xmi/Images/EAID_48D364F0_DCA4_41e8_B4D4_509B3023B969.svg +17 -0
  131. data/examples/xmi/Images/EAID_4DBDAB9E_4C1C_4cb1_A767_06BD743A50A7.svg +78 -0
  132. data/examples/xmi/Images/EAID_4EB75007_B31D_4f2c_8855_7E9D3A3B17F4.svg +454 -0
  133. data/examples/xmi/Images/EAID_4F421236_FCF3_4aae_B22A_C7E6A5EFBAC7.svg +81 -0
  134. data/examples/xmi/Images/EAID_4FC1D352_2102_4b73_BCB0_1410B29C6BD7.svg +379 -0
  135. data/examples/xmi/Images/EAID_4FE346EA_01E1_4b30_8BE6_BB32EA191E47.svg +126 -0
  136. data/examples/xmi/Images/EAID_5038EEE3_7DD0_4cca_9829_364E044D37E8.svg +199 -0
  137. data/examples/xmi/Images/EAID_508A37DC_9378_4f5a_BD96_48F4D24E03A5.svg +162 -0
  138. data/examples/xmi/Images/EAID_516DA1A2_F0EC_415c_9664_E4CA54E7F05C.svg +136 -0
  139. data/examples/xmi/Images/EAID_52A1DBD3_D3DA_4b6d_8F96_FC6F39F64242.svg +161 -0
  140. data/examples/xmi/Images/EAID_575E87BA_32E9_4a84_AA4E_0EFDFC5D4C07.svg +71 -0
  141. data/examples/xmi/Images/EAID_57E0F1A0_6C72_47ef_B922_B806F9A875E8.svg +209 -0
  142. data/examples/xmi/Images/EAID_5957C373_3FC1_482f_8F35_D809153A17F5.svg +123 -0
  143. data/examples/xmi/Images/EAID_59A66AE2_412C_48a6_BFC7_EA56CF11D269.svg +218 -0
  144. data/examples/xmi/Images/EAID_5A43833E_680B_4a90_8931_0C902304E029.svg +236 -0
  145. data/examples/xmi/Images/EAID_5D6DB5A0_5047_4bac_9E60_69904A60B56D.svg +353 -0
  146. data/examples/xmi/Images/EAID_5DA1E7A7_8E59_4803_A831_E9F3EC27328F.svg +242 -0
  147. data/examples/xmi/Images/EAID_5E2C1E2A_82A8_47f4_B2ED_1398D72BFCFD.svg +246 -0
  148. data/examples/xmi/Images/EAID_6052620C_4BD5_49f6_A21C_AD7E6DCA2795.svg +290 -0
  149. data/examples/xmi/Images/EAID_6481E2CC_35A6_43b0_88D4_10A667A2BC2D.svg +60 -0
  150. data/examples/xmi/Images/EAID_660C7D03_A26C_4977_A7BA_9D0A773DA811.svg +318 -0
  151. data/examples/xmi/Images/EAID_671F3C3D_35B6_4514_B5B6_DD7E84925493.svg +24 -0
  152. data/examples/xmi/Images/EAID_676B9C9A_D85F_4d2f_A46B_73F02090DC87.svg +127 -0
  153. data/examples/xmi/Images/EAID_6797FEFA_5801_48e4_8B9C_3C824C0E165D.svg +412 -0
  154. data/examples/xmi/Images/EAID_6807F4EE_18EF_4e7e_ACCF_D5BD323AFDE9.svg +130 -0
  155. data/examples/xmi/Images/EAID_69E81E34_CF28_4c7f_A48F_5941BA85CEE3.svg +96 -0
  156. data/examples/xmi/Images/EAID_6A3C55E8_3C3C_4f3a_8AAC_0299C5B23070.svg +10 -0
  157. data/examples/xmi/Images/EAID_6BAC333E_E2C2_42c7_8DDF_6B4FA0FFC03B.svg +143 -0
  158. data/examples/xmi/Images/EAID_6D0349D5_3F1B_4b28_82D2_910743DEB5E5.svg +114 -0
  159. data/examples/xmi/Images/EAID_6E95B74E_8A09_4698_9E9E_23BCFD2CE194.svg +37 -0
  160. data/examples/xmi/Images/EAID_70C77F92_5614_4b22_8C8E_67859F59D8FD.svg +254 -0
  161. data/examples/xmi/Images/EAID_71F9216B_E7A7_4083_B08E_6C71B57F3A1F.svg +187 -0
  162. data/examples/xmi/Images/EAID_73025C5A_08FC_47ff_AB2F_C7F79CF54B41.svg +145 -0
  163. data/examples/xmi/Images/EAID_74C974B6_6D07_425d_B7AC_C8899E3B4967.svg +76 -0
  164. data/examples/xmi/Images/EAID_7504FCD2_524C_4e7d_BAE4_4E58A8A8A12C.svg +196 -0
  165. data/examples/xmi/Images/EAID_78030266_3603_4747_9D75_03D16614BE7D.svg +35 -0
  166. data/examples/xmi/Images/EAID_785226C1_12B1_4104_A4C1_F19B70B9FB71.svg +348 -0
  167. data/examples/xmi/Images/EAID_7854470F_26B8_4d3c_AFDF_C05BCE6ED0CD.svg +72 -0
  168. data/examples/xmi/Images/EAID_794F4A8F_18CA_4e9f_8477_A6F0E5ED22D4.svg +187 -0
  169. data/examples/xmi/Images/EAID_7A24839E_C8AE_424d_B7D2_6DA16DC813E7.svg +114 -0
  170. data/examples/xmi/Images/EAID_7A3649FD_E960_4ae6_B9B1_A9001C066AE7.svg +181 -0
  171. data/examples/xmi/Images/EAID_7B2C6765_AB68_439a_87F3_DAC323CB2AF5.svg +196 -0
  172. data/examples/xmi/Images/EAID_7C44AC09_27C1_47b3_9A85_88EC71C081FF.svg +55 -0
  173. data/examples/xmi/Images/EAID_7CE102CA_97C1_4cac_BD3B_0500D3712D2A.svg +195 -0
  174. data/examples/xmi/Images/EAID_7D960BD8_65D8_4934_9C11_4EF860DD8FBA.svg +90 -0
  175. data/examples/xmi/Images/EAID_80939C98_A456_48c3_BCEA_4B72851F2DF6.svg +174 -0
  176. data/examples/xmi/Images/EAID_812FE862_76ED_44f0_B678_7A4601B395CF.svg +142 -0
  177. data/examples/xmi/Images/EAID_81B76F5B_9D64_4bbf_8AC8_34234FB87533.svg +740 -0
  178. data/examples/xmi/Images/EAID_84352F1A_195B_411b_9552_5BFC40BF90B5.svg +105 -0
  179. data/examples/xmi/Images/EAID_846DD800_139C_4d47_A1DF_3FB1AC5D130F.svg +554 -0
  180. data/examples/xmi/Images/EAID_84A9C65B_FD6D_4bb5_818F_E8C35FF5BCD1.svg +228 -0
  181. data/examples/xmi/Images/EAID_853674F5_7DC9_4aae_809B_5728098B5D5B.svg +154 -0
  182. data/examples/xmi/Images/EAID_860CBBFB_2F27_408f_9144_751F9D1F487F.svg +273 -0
  183. data/examples/xmi/Images/EAID_87476527_7B9B_4b92_967E_3D38365470CA.svg +239 -0
  184. data/examples/xmi/Images/EAID_87DAE930_5069_4c58_AC65_4B0B2C0F32C8.svg +10 -0
  185. data/examples/xmi/Images/EAID_88AF6BD7_BC34_406f_BB59_47CFAB4A7D5D.svg +116 -0
  186. data/examples/xmi/Images/EAID_88D0CB44_20D0_44fc_A6E3_B663332EF401.svg +200 -0
  187. data/examples/xmi/Images/EAID_8BB1CA0C_C003_4678_973B_A1C3308E021D.svg +136 -0
  188. data/examples/xmi/Images/EAID_8DAB169F_D189_4320_A0F5_4443E3297F0E.svg +181 -0
  189. data/examples/xmi/Images/EAID_8FD488EF_BAAB_40ec_A7ED_F7CC831D546E.svg +324 -0
  190. data/examples/xmi/Images/EAID_90BCA409_BB45_42c5_AFA5_45FE3D995904.svg +342 -0
  191. data/examples/xmi/Images/EAID_926AFE38_01FA_469e_B6AA_ED5F4D62B66F.svg +105 -0
  192. data/examples/xmi/Images/EAID_92AB0FD0_B0FB_4ceb_8EAE_66B6600D31D7.svg +681 -0
  193. data/examples/xmi/Images/EAID_92C43670_3057_47f1_A576_C60843FF3D26.svg +136 -0
  194. data/examples/xmi/Images/EAID_93F63576_BE01_4cd8_8A91_C674FF77FC3D.svg +718 -0
  195. data/examples/xmi/Images/EAID_9400D9BC_05A5_41fc_83F7_02E5C67F9718.svg +487 -0
  196. data/examples/xmi/Images/EAID_95246DCF_1C09_4a16_9512_98000F56B3D8.svg +292 -0
  197. data/examples/xmi/Images/EAID_9994BF62_51E2_42cd_BB35_16C537B6718A.svg +715 -0
  198. data/examples/xmi/Images/EAID_9AAD6C21_B1E7_4472_B64A_FB5E3569D970.svg +116 -0
  199. data/examples/xmi/Images/EAID_9BD7189A_877B_4ca9_B42C_817DEF144FB2.svg +284 -0
  200. data/examples/xmi/Images/EAID_9DA6C553_94FC_4204_83AD_ECC4B45A53EF.svg +159 -0
  201. data/examples/xmi/Images/EAID_9EE6A41B_5FAA_4c89_B98F_732059778630.svg +10 -0
  202. data/examples/xmi/Images/EAID_9F1A4B54_46F6_435c_9529_E43E54CF6050.svg +172 -0
  203. data/examples/xmi/Images/EAID_9FE1EA7B_4CEF_4976_A281_93A94315BD84.svg +153 -0
  204. data/examples/xmi/Images/EAID_A0695647_6172_4262_8C30_67441399609C.svg +290 -0
  205. data/examples/xmi/Images/EAID_A081C63E_D6F2_41a7_A99C_307836754AFA.svg +149 -0
  206. data/examples/xmi/Images/EAID_A24E2778_5AD9_44f2_AB8F_5CD3913477D6.svg +194 -0
  207. data/examples/xmi/Images/EAID_A264F089_F9B3_406c_A3A8_FF34903797D3.svg +143 -0
  208. data/examples/xmi/Images/EAID_A282E5D1_2A13_4e7f_BC76_5D086DD4A577.svg +357 -0
  209. data/examples/xmi/Images/EAID_A3BCE1D6_9DB5_4272_A020_4C0E194B99CC.svg +171 -0
  210. data/examples/xmi/Images/EAID_A56E3818_D1B8_4b63_B69E_FBAC4A8AF482.svg +218 -0
  211. data/examples/xmi/Images/EAID_A57215D5_75C5_4532_BCF4_264A77CD62F1.svg +204 -0
  212. data/examples/xmi/Images/EAID_A59065AF_9669_486c_9582_9693177CFC7F.svg +263 -0
  213. data/examples/xmi/Images/EAID_A759374D_589A_488c_99EF_537ACB9B1FF9.svg +398 -0
  214. data/examples/xmi/Images/EAID_A7B25F46_F18A_4373_B16D_8C6AC0B868B0.svg +174 -0
  215. data/examples/xmi/Images/EAID_A9FE9E6F_A5F4_47e5_A6BA_26E22C7346B6.svg +310 -0
  216. data/examples/xmi/Images/EAID_AA62CDEB_55EC_498d_B326_4AA2C9AF6A05.svg +144 -0
  217. data/examples/xmi/Images/EAID_AAF52AF6_F7F9_4005_AE46_8920847BEA03.svg +144 -0
  218. data/examples/xmi/Images/EAID_AB281AC1_7CB8_404a_8124_34343DDD84E2.svg +198 -0
  219. data/examples/xmi/Images/EAID_AB7F1FDF_A66B_42a1_B8A3_7F594BAAD508.svg +143 -0
  220. data/examples/xmi/Images/EAID_AC2191E3_76E3_40b2_9E21_0E0B9B5277D2.svg +114 -0
  221. data/examples/xmi/Images/EAID_AD451676_A7C8_4c6a_A925_A9B9CA344142.svg +339 -0
  222. data/examples/xmi/Images/EAID_ADBA40A1_9375_4c1b_9938_0990612EB615.svg +429 -0
  223. data/examples/xmi/Images/EAID_ADC8773C_1B27_48ac_BAC1_14C1C919FAF6.svg +245 -0
  224. data/examples/xmi/Images/EAID_AE0718DF_AF69_4ea1_A099_E20028FE40A1.svg +173 -0
  225. data/examples/xmi/Images/EAID_B0DDB85D_A00C_4a7f_8C06_CCA15E5E4FE5.svg +31 -0
  226. data/examples/xmi/Images/EAID_B27ED282_D5E5_4f33_8AC1_62802F9E0B35.svg +256 -0
  227. data/examples/xmi/Images/EAID_B3AFECCB_17DD_44d6_8A44_2C38D9A64C0B.svg +95 -0
  228. data/examples/xmi/Images/EAID_B3B6C5B1_278E_4714_8244_B6C28B66AB50.svg +176 -0
  229. data/examples/xmi/Images/EAID_B53E76CD_A0F2_4e2f_B3AB_796D85964EF2.svg +179 -0
  230. data/examples/xmi/Images/EAID_B55D6E67_0BDD_4163_B359_11A6FBA89C74.svg +207 -0
  231. data/examples/xmi/Images/EAID_B58D1A53_E860_41a3_8352_11C274093E83.svg +189 -0
  232. data/examples/xmi/Images/EAID_B62C02B3_69DB_49e9_8089_4EE398BDE666.svg +165 -0
  233. data/examples/xmi/Images/EAID_BC008774_B539_4150_8174_B675989053D0.svg +22 -0
  234. data/examples/xmi/Images/EAID_BC1F7E00_082D_4a26_922B_3967A8D66859.svg +266 -0
  235. data/examples/xmi/Images/EAID_BDA613D8_402A_475a_AA15_683D88FD3D23.svg +183 -0
  236. data/examples/xmi/Images/EAID_C028B286_4C85_47d8_B6D5_80B28F556E82.svg +303 -0
  237. data/examples/xmi/Images/EAID_C173A6F4_1D1B_400e_AD8C_64FFF7CD5BE5.svg +178 -0
  238. data/examples/xmi/Images/EAID_C1834072_CADC_4ce4_B0FC_8284AE5CF4A4.svg +158 -0
  239. data/examples/xmi/Images/EAID_C1EC985B_5CBD_4e91_8661_EB4EF23781D9.svg +286 -0
  240. data/examples/xmi/Images/EAID_C31C1314_B679_4413_B8FE_A2CD584FC128.svg +305 -0
  241. data/examples/xmi/Images/EAID_C37CFBD6_69BA_42fb_9AC7_2D329D931BCF.svg +171 -0
  242. data/examples/xmi/Images/EAID_C857C934_306F_463a_87D5_257CB225ECFE.svg +174 -0
  243. data/examples/xmi/Images/EAID_C96797DE_2238_42d3_896A_9F92500270ED.svg +180 -0
  244. data/examples/xmi/Images/EAID_C96CBC24_B20E_459a_8F9D_75B61CDCB89F.svg +656 -0
  245. data/examples/xmi/Images/EAID_CACB523D_56A5_4f05_B3C2_51BB18F380FD.svg +158 -0
  246. data/examples/xmi/Images/EAID_CB34B578_101B_48b4_9271_214FFEA6A83A.svg +409 -0
  247. data/examples/xmi/Images/EAID_CBBD6CF4_0A1E_4406_9930_89DE43527910.svg +361 -0
  248. data/examples/xmi/Images/EAID_CC06A828_3750_472f_8DB2_C2E0863FCE17.svg +96 -0
  249. data/examples/xmi/Images/EAID_CD5CF053_1772_4a0f_962D_B17054D8EEAA.svg +173 -0
  250. data/examples/xmi/Images/EAID_CE440B5A_9534_4c75_9BA5_50862BB396C2.svg +97 -0
  251. data/examples/xmi/Images/EAID_CE4734FC_7986_4b3a_807F_A5B2C7EDE9E4.svg +193 -0
  252. data/examples/xmi/Images/EAID_D14AA320_9D41_4366_8739_9C2C21F96AE1.svg +32 -0
  253. data/examples/xmi/Images/EAID_D2FA55D3_C733_4a4d_92D0_0BC7AC0BB5BC.svg +108 -0
  254. data/examples/xmi/Images/EAID_D351FC34_FB03_488d_ADA4_BDB93DA9CB02.svg +49 -0
  255. data/examples/xmi/Images/EAID_D368FDF3_BDC5_4718_A701_351C8587A376.svg +592 -0
  256. data/examples/xmi/Images/EAID_D4DA8C48_3998_450d_87C4_9D65C9FECDB4.svg +42 -0
  257. data/examples/xmi/Images/EAID_D5464ECF_290E_4b2b_A6C4_25BE80F886CB.svg +76 -0
  258. data/examples/xmi/Images/EAID_D55235B0_61E9_461a_8379_2B8BF2403BE2.svg +147 -0
  259. data/examples/xmi/Images/EAID_D555ED73_F010_45d7_8A53_45A33C64C249.svg +318 -0
  260. data/examples/xmi/Images/EAID_D7AAC526_267E_45a0_A853_3207F02363F8.svg +45 -0
  261. data/examples/xmi/Images/EAID_D998B20D_A875_4ef8_A9CE_996BE56602BD.svg +158 -0
  262. data/examples/xmi/Images/EAID_DBFA8B39_F5B7_4c0e_9552_19AEAE5BA64E.svg +200 -0
  263. data/examples/xmi/Images/EAID_DE47A47D_E7BE_4e6f_BA81_F789EE8CFE72.svg +61 -0
  264. data/examples/xmi/Images/EAID_DFBB1072_8EC5_4384_8241_7EDF4B6B888B.svg +78 -0
  265. data/examples/xmi/Images/EAID_E325B9D8_E955_4aed_8125_63167BD40320.svg +67 -0
  266. data/examples/xmi/Images/EAID_E32D9D02_CAE9_4a47_92A8_3290EDCD6E6D.svg +79 -0
  267. data/examples/xmi/Images/EAID_E3B28611_7857_458a_B0BC_736E777B88EC.svg +194 -0
  268. data/examples/xmi/Images/EAID_E43C37EC_1176_4d2e_8B98_B6F3DFF6A092.svg +96 -0
  269. data/examples/xmi/Images/EAID_E591C1CF_7F35_4160_8A72_DFA097AD5811.svg +271 -0
  270. data/examples/xmi/Images/EAID_E77C66A2_2E94_4196_BFC6_662FE5AEEB6F.svg +332 -0
  271. data/examples/xmi/Images/EAID_E7AABA98_2450_4986_9736_DCCAF0108C50.svg +639 -0
  272. data/examples/xmi/Images/EAID_E7D9A2C4_72D6_40b9_8EB8_6B35476246B3.svg +134 -0
  273. data/examples/xmi/Images/EAID_E9CDAD85_ECF1_43de_819F_30A0D01785E6.svg +193 -0
  274. data/examples/xmi/Images/EAID_EC8AF507_F441_4e8a_B8A7_C1690F3C7D0B.svg +58 -0
  275. data/examples/xmi/Images/EAID_ED501058_D540_47ac_8EBC_5921E8C0BF57.svg +384 -0
  276. data/examples/xmi/Images/EAID_EFBF5F0F_DF74_4944_8791_114F5637C335.svg +590 -0
  277. data/examples/xmi/Images/EAID_EFFFA027_2A1F_425c_8437_BF89AADC8893.svg +365 -0
  278. data/examples/xmi/Images/EAID_F07E7718_B2C2_4a65_B5DD_477CB73E971E.svg +165 -0
  279. data/examples/xmi/Images/EAID_F0F20BDF_C729_47f7_B6FC_25ED2C4609CA.svg +61 -0
  280. data/examples/xmi/Images/EAID_F32E5AFE_8605_4c77_AE69_D0D0A6E380AC.svg +76 -0
  281. data/examples/xmi/Images/EAID_F3F00F45_CD37_46fd_B521_D1040EB2FB16.svg +123 -0
  282. data/examples/xmi/Images/EAID_F46E8F19_D8F1_4a3d_B87B_B0BAB4F50F50.svg +202 -0
  283. data/examples/xmi/Images/EAID_F48E5F6E_2411_4635_9315_3EAA4CFA29F7.svg +351 -0
  284. data/examples/xmi/Images/EAID_F4C23F9E_DD74_4fed_B75D_AD3C6448BA24.svg +189 -0
  285. data/examples/xmi/Images/EAID_F853B3C4_B145_4ef0_B261_C3CC0475B6D2.svg +215 -0
  286. data/examples/xmi/Images/EAID_F8BE68CA_1F8F_47e5_9454_01A2EB7D388A.svg +124 -0
  287. data/examples/xmi/Images/EAID_F92A6A28_612E_468e_9E39_D7AE7D24E24D.svg +208 -0
  288. data/examples/xmi/Images/EAID_F995FA49_B86E_4c94_BE5E_C928FB6B87D0.svg +302 -0
  289. data/examples/xmi/Images/EAID_FEAE013A_A4E4_4283_A491_1FEB8D0EBA28.svg +524 -0
  290. data/examples/xmi/Images/EAID_FEBE5726_3751_470b_9023_8C569202E97E.svg +730 -0
  291. data/examples/xmi/UML_EA.DTD +6856 -0
  292. data/examples/xmi/UmlModel_template.xmi +23 -0
  293. data/examples/xmi/basic.xmi +9086 -0
  294. data/examples/xmi/simple.xmi +655 -0
  295. data/examples/xmi/simple_example.xmi +23 -0
  296. data/examples/xmi/test.xmi +1703 -0
  297. data/exe/lutaml +2 -16
  298. data/exe/lutaml-wsd2uml +3 -3
  299. data/exe/lutaml-yaml2uml +2 -2
  300. data/lib/lutaml/cli/commands/base_command.rb +118 -0
  301. data/lib/lutaml/cli/element_identifier.rb +165 -0
  302. data/lib/lutaml/cli/enhanced_formatter.rb +504 -0
  303. data/lib/lutaml/cli/interactive_shell.rb +911 -0
  304. data/lib/lutaml/cli/lml_commands.rb +201 -0
  305. data/lib/lutaml/cli/output_formatter.rb +348 -0
  306. data/lib/lutaml/cli/resource_registry.rb +127 -0
  307. data/lib/lutaml/cli/tree_view_formatter.rb +308 -0
  308. data/lib/lutaml/cli/uml/build_command.rb +538 -0
  309. data/lib/lutaml/cli/uml/diagram_command.rb +417 -0
  310. data/lib/lutaml/cli/uml/export_command.rb +78 -0
  311. data/lib/lutaml/cli/uml/find_command.rb +122 -0
  312. data/lib/lutaml/cli/uml/info_command.rb +104 -0
  313. data/lib/lutaml/cli/uml/inspect_command.rb +88 -0
  314. data/lib/lutaml/cli/uml/ls_command.rb +105 -0
  315. data/lib/lutaml/cli/uml/repl_command.rb +50 -0
  316. data/lib/lutaml/cli/uml/search_command.rb +88 -0
  317. data/lib/lutaml/cli/uml/serve_command.rb +59 -0
  318. data/lib/lutaml/cli/uml/shared_helpers.rb +51 -0
  319. data/lib/lutaml/cli/uml/spa_command.rb +209 -0
  320. data/lib/lutaml/cli/uml/stats_command.rb +60 -0
  321. data/lib/lutaml/cli/uml/tree_command.rb +85 -0
  322. data/lib/lutaml/cli/uml/validate_command.rb +195 -0
  323. data/lib/lutaml/cli/uml/verify_command.rb +107 -0
  324. data/lib/lutaml/cli/uml_commands.rb +163 -0
  325. data/lib/lutaml/cli.rb +72 -0
  326. data/lib/lutaml/command_line.rb +8 -6
  327. data/lib/lutaml/converter/dsl_to_uml.rb +2 -0
  328. data/lib/lutaml/converter/xmi_to_uml.rb +51 -26
  329. data/lib/lutaml/ea/diagram/configuration.rb +379 -0
  330. data/lib/lutaml/ea/diagram/element_renderers/base_renderer.rb +81 -0
  331. data/lib/lutaml/ea/diagram/element_renderers/class_renderer.rb +330 -0
  332. data/lib/lutaml/ea/diagram/element_renderers/connector_renderer.rb +55 -0
  333. data/lib/lutaml/ea/diagram/element_renderers/package_renderer.rb +69 -0
  334. data/lib/lutaml/ea/diagram/extractor.rb +564 -0
  335. data/lib/lutaml/ea/diagram/layout_engine.rb +251 -0
  336. data/lib/lutaml/ea/diagram/path_builder.rb +258 -0
  337. data/lib/lutaml/ea/diagram/style_parser.rb +315 -0
  338. data/lib/lutaml/ea/diagram/style_resolver.rb +291 -0
  339. data/lib/lutaml/ea/diagram/svg_renderer.rb +285 -0
  340. data/lib/lutaml/ea/diagram/util.rb +69 -0
  341. data/lib/lutaml/ea/diagram.rb +77 -0
  342. data/lib/lutaml/express/parsers/exp.rb +1 -1
  343. data/lib/lutaml/express.rb +4 -2
  344. data/lib/lutaml/formatter/base.rb +6 -6
  345. data/lib/lutaml/formatter/graphviz.rb +10 -8
  346. data/lib/lutaml/formatter.rb +3 -0
  347. data/lib/lutaml/layout/engine.rb +9 -7
  348. data/lib/lutaml/layout/graph_viz_engine.rb +2 -1
  349. data/lib/lutaml/layout.rb +8 -0
  350. data/lib/lutaml/model_transformations/configuration.rb +333 -0
  351. data/lib/lutaml/model_transformations/format_registry.rb +394 -0
  352. data/lib/lutaml/model_transformations/parsers/base_parser.rb +466 -0
  353. data/lib/lutaml/model_transformations/parsers/qea_parser.rb +455 -0
  354. data/lib/lutaml/model_transformations/parsers/xmi_parser.rb +301 -0
  355. data/lib/lutaml/model_transformations/transformation_engine.rb +409 -0
  356. data/lib/lutaml/model_transformations.rb +143 -0
  357. data/lib/lutaml/parser.rb +15 -7
  358. data/lib/lutaml/qea/benchmark.rb +212 -0
  359. data/lib/lutaml/qea/database.rb +324 -0
  360. data/lib/lutaml/qea/factory/association_transformer.rb +115 -0
  361. data/lib/lutaml/qea/factory/attribute_tag_transformer.rb +60 -0
  362. data/lib/lutaml/qea/factory/attribute_transformer.rb +103 -0
  363. data/lib/lutaml/qea/factory/base_transformer.rb +132 -0
  364. data/lib/lutaml/qea/factory/class_transformer.rb +723 -0
  365. data/lib/lutaml/qea/factory/constraint_transformer.rb +78 -0
  366. data/lib/lutaml/qea/factory/data_type_transformer.rb +155 -0
  367. data/lib/lutaml/qea/factory/diagram_transformer.rb +179 -0
  368. data/lib/lutaml/qea/factory/document_builder.rb +275 -0
  369. data/lib/lutaml/qea/factory/ea_to_uml_factory.rb +260 -0
  370. data/lib/lutaml/qea/factory/enum_transformer.rb +85 -0
  371. data/lib/lutaml/qea/factory/generalization_transformer.rb +106 -0
  372. data/lib/lutaml/qea/factory/instance_transformer.rb +96 -0
  373. data/lib/lutaml/qea/factory/object_property_transformer.rb +61 -0
  374. data/lib/lutaml/qea/factory/operation_transformer.rb +75 -0
  375. data/lib/lutaml/qea/factory/package_transformer.rb +225 -0
  376. data/lib/lutaml/qea/factory/reference_resolver.rb +99 -0
  377. data/lib/lutaml/qea/factory/tagged_value_transformer.rb +41 -0
  378. data/lib/lutaml/qea/factory/transformer_registry.rb +85 -0
  379. data/lib/lutaml/qea/file_detector.rb +178 -0
  380. data/lib/lutaml/qea/infrastructure/database_connection.rb +100 -0
  381. data/lib/lutaml/qea/infrastructure/schema_reader.rb +136 -0
  382. data/lib/lutaml/qea/infrastructure/table_reader.rb +224 -0
  383. data/lib/lutaml/qea/models/base_model.rb +48 -0
  384. data/lib/lutaml/qea/models/ea_attribute.rb +135 -0
  385. data/lib/lutaml/qea/models/ea_attribute_tag.rb +109 -0
  386. data/lib/lutaml/qea/models/ea_complexity_type.rb +81 -0
  387. data/lib/lutaml/qea/models/ea_connector.rb +162 -0
  388. data/lib/lutaml/qea/models/ea_connector_type.rb +62 -0
  389. data/lib/lutaml/qea/models/ea_constraint_type.rb +65 -0
  390. data/lib/lutaml/qea/models/ea_datatype.rb +108 -0
  391. data/lib/lutaml/qea/models/ea_diagram.rb +117 -0
  392. data/lib/lutaml/qea/models/ea_diagram_link.rb +80 -0
  393. data/lib/lutaml/qea/models/ea_diagram_object.rb +86 -0
  394. data/lib/lutaml/qea/models/ea_diagram_type.rb +58 -0
  395. data/lib/lutaml/qea/models/ea_document.rb +68 -0
  396. data/lib/lutaml/qea/models/ea_object.rb +208 -0
  397. data/lib/lutaml/qea/models/ea_object_constraint.rb +62 -0
  398. data/lib/lutaml/qea/models/ea_object_property.rb +96 -0
  399. data/lib/lutaml/qea/models/ea_object_type.rb +75 -0
  400. data/lib/lutaml/qea/models/ea_operation.rb +153 -0
  401. data/lib/lutaml/qea/models/ea_operation_param.rb +73 -0
  402. data/lib/lutaml/qea/models/ea_package.rb +75 -0
  403. data/lib/lutaml/qea/models/ea_script.rb +69 -0
  404. data/lib/lutaml/qea/models/ea_status_type.rb +68 -0
  405. data/lib/lutaml/qea/models/ea_stereotype.rb +59 -0
  406. data/lib/lutaml/qea/models/ea_tagged_value.rb +105 -0
  407. data/lib/lutaml/qea/models/ea_xref.rb +174 -0
  408. data/lib/lutaml/qea/parser.rb +61 -0
  409. data/lib/lutaml/qea/repositories/base_repository.rb +215 -0
  410. data/lib/lutaml/qea/repositories/object_repository.rb +221 -0
  411. data/lib/lutaml/qea/services/configuration.rb +211 -0
  412. data/lib/lutaml/qea/services/database_loader.rb +215 -0
  413. data/lib/lutaml/qea/validation/association_validator.rb +75 -0
  414. data/lib/lutaml/qea/validation/attribute_validator.rb +103 -0
  415. data/lib/lutaml/qea/validation/base_validator.rb +310 -0
  416. data/lib/lutaml/qea/validation/class_validator.rb +123 -0
  417. data/lib/lutaml/qea/validation/database/circular_reference_validator.rb +111 -0
  418. data/lib/lutaml/qea/validation/database/orphan_validator.rb +155 -0
  419. data/lib/lutaml/qea/validation/database/referential_integrity_validator.rb +130 -0
  420. data/lib/lutaml/qea/validation/diagram_validator.rb +114 -0
  421. data/lib/lutaml/qea/validation/formatters/json_formatter.rb +137 -0
  422. data/lib/lutaml/qea/validation/formatters/text_formatter.rb +235 -0
  423. data/lib/lutaml/qea/validation/operation_validator.rb +81 -0
  424. data/lib/lutaml/qea/validation/package_validator.rb +113 -0
  425. data/lib/lutaml/qea/validation/validation_engine.rb +497 -0
  426. data/lib/lutaml/qea/validation/validation_message.rb +144 -0
  427. data/lib/lutaml/qea/validation/validation_result.rb +212 -0
  428. data/lib/lutaml/qea/validation/validator_registry.rb +134 -0
  429. data/lib/lutaml/qea/verification/comparison_result.rb +264 -0
  430. data/lib/lutaml/qea/verification/document_normalizer.rb +169 -0
  431. data/lib/lutaml/qea/verification/document_verifier.rb +330 -0
  432. data/lib/lutaml/qea/verification/element_comparator.rb +306 -0
  433. data/lib/lutaml/qea/verification/structure_matcher.rb +287 -0
  434. data/lib/lutaml/qea.rb +226 -0
  435. data/lib/lutaml/sysml/allocate.rb +2 -0
  436. data/lib/lutaml/sysml/allocated.rb +2 -0
  437. data/lib/lutaml/sysml/binding_connector.rb +2 -0
  438. data/lib/lutaml/sysml/block.rb +2 -0
  439. data/lib/lutaml/sysml/constraint_block.rb +2 -0
  440. data/lib/lutaml/sysml/copy.rb +2 -0
  441. data/lib/lutaml/sysml/derive_requirement.rb +2 -0
  442. data/lib/lutaml/sysml/nested_connector_end.rb +2 -0
  443. data/lib/lutaml/sysml/refine.rb +2 -0
  444. data/lib/lutaml/sysml/requirement.rb +2 -0
  445. data/lib/lutaml/sysml/requirement_related.rb +2 -0
  446. data/lib/lutaml/sysml/satisfy.rb +2 -0
  447. data/lib/lutaml/sysml/test_case.rb +2 -0
  448. data/lib/lutaml/sysml/trace.rb +2 -0
  449. data/lib/lutaml/sysml/verify.rb +2 -0
  450. data/lib/lutaml/sysml/xmi_file.rb +2 -0
  451. data/lib/lutaml/sysml.rb +3 -1
  452. data/lib/lutaml/uml/association.rb +4 -0
  453. data/lib/lutaml/uml/class.rb +11 -9
  454. data/lib/lutaml/uml/classifier.rb +3 -0
  455. data/lib/lutaml/uml/comment.rb +13 -0
  456. data/lib/lutaml/uml/data_type.rb +7 -6
  457. data/lib/lutaml/uml/diagram.rb +12 -0
  458. data/lib/lutaml/uml/diagram_link.rb +26 -0
  459. data/lib/lutaml/uml/diagram_object.rb +30 -0
  460. data/lib/lutaml/uml/document.rb +18 -0
  461. data/lib/lutaml/uml/enum.rb +4 -3
  462. data/lib/lutaml/uml/fontname.rb +13 -0
  463. data/lib/lutaml/uml/generalization.rb +2 -0
  464. data/lib/lutaml/uml/group.rb +2 -0
  465. data/lib/lutaml/uml/namespace.rb +2 -2
  466. data/lib/lutaml/uml/node/{field.rb → attribute.rb} +4 -4
  467. data/lib/lutaml/uml/node/base.rb +1 -1
  468. data/lib/lutaml/uml/node/class_node.rb +12 -12
  469. data/lib/lutaml/uml/node/class_relationship.rb +2 -2
  470. data/lib/lutaml/uml/node/document.rb +2 -2
  471. data/lib/lutaml/uml/node/method_argument.rb +3 -3
  472. data/lib/lutaml/uml/node/{method.rb → operation.rb} +4 -4
  473. data/lib/lutaml/uml/node/relationship.rb +3 -3
  474. data/lib/lutaml/uml/package.rb +7 -4
  475. data/lib/lutaml/uml/package_path.rb +235 -0
  476. data/lib/lutaml/uml/parsers/attribute.rb +2 -2
  477. data/lib/lutaml/uml/parsers/dsl.rb +3 -4
  478. data/lib/lutaml/uml/parsers/yaml.rb +1 -1
  479. data/lib/lutaml/uml/qualified_name.rb +178 -0
  480. data/lib/lutaml/uml/tagged_value.rb +21 -0
  481. data/lib/lutaml/uml/top_element.rb +7 -1
  482. data/lib/lutaml/uml/top_element_attribute.rb +4 -0
  483. data/lib/lutaml/uml/validation/document_structure_validator.rb +389 -0
  484. data/lib/lutaml/uml.rb +89 -45
  485. data/lib/lutaml/uml_repository/error_handler.rb +203 -0
  486. data/lib/lutaml/uml_repository/exporters/base_exporter.rb +61 -0
  487. data/lib/lutaml/uml_repository/exporters/json_exporter.rb +344 -0
  488. data/lib/lutaml/uml_repository/exporters/markdown_exporter.rb +598 -0
  489. data/lib/lutaml/uml_repository/index_builder.rb +478 -0
  490. data/lib/lutaml/uml_repository/lazy_repository.rb +238 -0
  491. data/lib/lutaml/uml_repository/package_exporter.rb +336 -0
  492. data/lib/lutaml/uml_repository/package_loader.rb +220 -0
  493. data/lib/lutaml/uml_repository/package_metadata.rb +77 -0
  494. data/lib/lutaml/uml_repository/presenters/association_presenter.rb +86 -0
  495. data/lib/lutaml/uml_repository/presenters/attribute_presenter.rb +101 -0
  496. data/lib/lutaml/uml_repository/presenters/class_presenter.rb +75 -0
  497. data/lib/lutaml/uml_repository/presenters/datatype_presenter.rb +108 -0
  498. data/lib/lutaml/uml_repository/presenters/diagram_presenter.rb +503 -0
  499. data/lib/lutaml/uml_repository/presenters/element_presenter.rb +92 -0
  500. data/lib/lutaml/uml_repository/presenters/enum_presenter.rb +83 -0
  501. data/lib/lutaml/uml_repository/presenters/package_presenter.rb +48 -0
  502. data/lib/lutaml/uml_repository/presenters/presenter_factory.rb +76 -0
  503. data/lib/lutaml/uml_repository/queries/association_query.rb +187 -0
  504. data/lib/lutaml/uml_repository/queries/base_query.rb +45 -0
  505. data/lib/lutaml/uml_repository/queries/class_query.rb +117 -0
  506. data/lib/lutaml/uml_repository/queries/diagram_query.rb +111 -0
  507. data/lib/lutaml/uml_repository/queries/inheritance_query.rb +325 -0
  508. data/lib/lutaml/uml_repository/queries/package_query.rb +239 -0
  509. data/lib/lutaml/uml_repository/queries/search_query.rb +357 -0
  510. data/lib/lutaml/uml_repository/query_dsl/conditions/base_condition.rb +28 -0
  511. data/lib/lutaml/uml_repository/query_dsl/conditions/block_condition.rb +46 -0
  512. data/lib/lutaml/uml_repository/query_dsl/conditions/hash_condition.rb +84 -0
  513. data/lib/lutaml/uml_repository/query_dsl/conditions/package_condition.rb +84 -0
  514. data/lib/lutaml/uml_repository/query_dsl/order.rb +90 -0
  515. data/lib/lutaml/uml_repository/query_dsl/query_builder.rb +296 -0
  516. data/lib/lutaml/uml_repository/repository.rb +798 -0
  517. data/lib/lutaml/uml_repository/repository_enhanced.rb +439 -0
  518. data/lib/lutaml/uml_repository/search_result.rb +86 -0
  519. data/lib/lutaml/uml_repository/static_site/configuration.rb +270 -0
  520. data/lib/lutaml/uml_repository/static_site/data_transformer.rb +967 -0
  521. data/lib/lutaml/uml_repository/static_site/generator.rb +401 -0
  522. data/lib/lutaml/uml_repository/static_site/id_generator.rb +115 -0
  523. data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +317 -0
  524. data/lib/lutaml/uml_repository/static_site.rb +88 -0
  525. data/lib/lutaml/uml_repository/statistics_calculator.rb +334 -0
  526. data/lib/lutaml/uml_repository/validators/repository_validator.rb +404 -0
  527. data/lib/lutaml/uml_repository/web_ui/app.rb +162 -0
  528. data/lib/lutaml/uml_repository/web_ui/public/app.js +452 -0
  529. data/lib/lutaml/uml_repository/web_ui/public/styles.css +381 -0
  530. data/lib/lutaml/uml_repository/web_ui/views/index.erb +40 -0
  531. data/lib/lutaml/uml_repository.rb +97 -0
  532. data/lib/lutaml/version.rb +3 -1
  533. data/lib/lutaml/xmi/liquid_drops/association_drop.rb +60 -58
  534. data/lib/lutaml/xmi/liquid_drops/attribute_drop.rb +55 -53
  535. data/lib/lutaml/xmi/liquid_drops/cardinality_drop.rb +15 -13
  536. data/lib/lutaml/xmi/liquid_drops/connector_drop.rb +50 -46
  537. data/lib/lutaml/xmi/liquid_drops/constraint_drop.rb +19 -17
  538. data/lib/lutaml/xmi/liquid_drops/data_type_drop.rb +93 -90
  539. data/lib/lutaml/xmi/liquid_drops/dependency_drop.rb +26 -24
  540. data/lib/lutaml/xmi/liquid_drops/diagram_drop.rb +26 -24
  541. data/lib/lutaml/xmi/liquid_drops/enum_drop.rb +40 -37
  542. data/lib/lutaml/xmi/liquid_drops/enum_owned_literal_drop.rb +20 -18
  543. data/lib/lutaml/xmi/liquid_drops/generalization_attribute_drop.rb +64 -62
  544. data/lib/lutaml/xmi/liquid_drops/generalization_drop.rb +142 -140
  545. data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +174 -170
  546. data/lib/lutaml/xmi/liquid_drops/operation_drop.rb +23 -21
  547. data/lib/lutaml/xmi/liquid_drops/package_drop.rb +95 -93
  548. data/lib/lutaml/xmi/liquid_drops/root_drop.rb +28 -25
  549. data/lib/lutaml/xmi/liquid_drops/source_target_drop.rb +39 -37
  550. data/lib/lutaml/xmi/parsers/xmi_base.rb +93 -166
  551. data/lib/lutaml/xmi/parsers/xml.rb +9 -9
  552. data/lib/lutaml/xmi.rb +37 -6
  553. data/lib/lutaml/xml/parsers/xml.rb +3 -1
  554. data/lib/lutaml/xml.rb +3 -1
  555. data/lib/lutaml.rb +14 -2
  556. data/lutaml.gemspec +19 -8
  557. data/plateau_all_packages.lur +0 -0
  558. data/templates/static_site/assets/scripts/app.js +45 -0
  559. data/templates/static_site/assets/scripts/core/state.js +419 -0
  560. data/templates/static_site/assets/scripts/core/utils.js +133 -0
  561. data/templates/static_site/assets/scripts/ui/details.js +74 -0
  562. data/templates/static_site/assets/scripts/ui/diagrams.js +345 -0
  563. data/templates/static_site/assets/scripts/ui/search.js +187 -0
  564. data/templates/static_site/assets/scripts/ui/sidebar.js +214 -0
  565. data/templates/static_site/assets/styles/00-variables.css +144 -0
  566. data/templates/static_site/assets/styles/01-reset.css +79 -0
  567. data/templates/static_site/assets/styles/02-base.css +149 -0
  568. data/templates/static_site/assets/styles/03-layout.css +171 -0
  569. data/templates/static_site/assets/styles/04-components.css +856 -0
  570. data/templates/static_site/assets/styles/05-utilities.css +89 -0
  571. data/templates/static_site/assets/styles/06-diagrams.css +277 -0
  572. data/templates/static_site/components/class_details.liquid +328 -0
  573. data/templates/static_site/components/content.liquid +508 -0
  574. data/templates/static_site/components/diagram_list.liquid +52 -0
  575. data/templates/static_site/components/diagram_viewer.liquid +71 -0
  576. data/templates/static_site/components/header.liquid +134 -0
  577. data/templates/static_site/components/package_details.liquid +119 -0
  578. data/templates/static_site/components/sidebar.liquid +46 -0
  579. data/templates/static_site/components/tree_node.liquid +81 -0
  580. data/templates/static_site/multi_file.liquid +46 -0
  581. data/templates/static_site/single_file.liquid +52 -0
  582. metadata +644 -28
  583. data/CODE_OF_CONDUCT.md +0 -74
  584. data/docs/lutaml-sysml.adoc +0 -10
@@ -0,0 +1,798 @@
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 an attribute by its qualified name.
349
+ #
350
+ # The qualified name format is "PackagePath::ClassName::attributeName".
351
+ # Splits off the last segment as the attribute name, finds the containing
352
+ # class, then returns the matching attribute.
353
+ #
354
+ # @param qualified_name [String] Qualified name of the attribute
355
+ # @return [Lutaml::Uml::Attribute, nil] The attribute or nil
356
+ # @example
357
+ # attr = repo.find_attribute("ModelRoot::Core::Building::name")
358
+ def find_attribute(qualified_name)
359
+ class_qname, _, attr_name = qualified_name.rpartition("::")
360
+ return nil if class_qname.empty?
361
+
362
+ klass = class_query.find_by_qname(class_qname)
363
+ return nil unless klass
364
+
365
+ attrs = klass.attributes
366
+ return nil unless attrs
367
+
368
+ attrs.find { |a| a.name == attr_name }
369
+ end
370
+
371
+ # Get all attributes across all classes in the repository.
372
+ #
373
+ # @return [Array<Lutaml::Uml::Attribute>] All attribute objects
374
+ def all_attributes
375
+ indexes[:qualified_names].flat_map do |_qname, entity|
376
+ next [] unless entity.respond_to?(:attributes) && entity.attributes
377
+
378
+ entity.attributes
379
+ end
380
+ end
381
+
382
+ # Find all classes with a specific stereotype.
383
+ #
384
+ # @param stereotype [String] The stereotype to search for
385
+ # @return [Array] Array of class objects with the stereotype
386
+ # @example
387
+ # feature_types = repo.find_classes_by_stereotype("featureType")
388
+ def find_classes_by_stereotype(stereotype)
389
+ class_query.find_by_stereotype(stereotype)
390
+ end
391
+
392
+ # Get classes in a specific package.
393
+ #
394
+ # @param package_path [String] The package path
395
+ # @param recursive [Boolean] Whether to include classes from nested
396
+ # packages (default: false)
397
+ # @return [Array] Array of class objects in the package
398
+ # @example
399
+ # classes = repo.classes_in_package("ModelRoot::i-UR::urf")
400
+ # all_classes = repo.classes_in_package(
401
+ # "ModelRoot::i-UR", recursive: true)
402
+ def classes_in_package(package_path, recursive: false)
403
+ class_query.in_package(package_path, recursive: recursive)
404
+ end
405
+
406
+ # Get the direct parent class (supertype).
407
+ #
408
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
409
+ # or qualified name string
410
+ # @return [Lutaml::Uml::Class, nil] The parent class, or nil if no parent
411
+ # @example
412
+ # parent = repo.supertype_of("ModelRoot::Child")
413
+ # parent = repo.supertype_of(child_class)
414
+ def supertype_of(class_or_qname)
415
+ inheritance_query.supertype(class_or_qname)
416
+ end
417
+
418
+ # Get direct child classes (subtypes).
419
+ #
420
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
421
+ # or qualified name string
422
+ # @param recursive [Boolean] Whether to include all descendants
423
+ # (default: false)
424
+ # @return [Array] Array of child class objects
425
+ # @example
426
+ # children = repo.subtypes_of("ModelRoot::Parent")
427
+ # all_descendants = repo.subtypes_of(
428
+ # "ModelRoot::Parent", recursive: true)
429
+ def subtypes_of(class_or_qname, recursive: false)
430
+ inheritance_query.subtypes(class_or_qname, recursive: recursive)
431
+ end
432
+
433
+ # Get all ancestor classes up to the root.
434
+ #
435
+ # Returns ancestors in order from immediate parent to root.
436
+ #
437
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
438
+ # or qualified name string
439
+ # @return [Array] Array of ancestor class objects, ordered from nearest
440
+ # to furthest
441
+ # @example
442
+ # ancestors = repo.ancestors_of("ModelRoot::GrandChild")
443
+ def ancestors_of(class_or_qname)
444
+ inheritance_query.ancestors(class_or_qname)
445
+ end
446
+
447
+ # Get all descendant classes.
448
+ #
449
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
450
+ # or qualified name string
451
+ # @param max_depth [Integer, nil] Maximum depth to traverse (nil for
452
+ # unlimited)
453
+ # @return [Array] Array of descendant class objects
454
+ # @example
455
+ # descendants = repo.descendants_of("ModelRoot::Parent", max_depth: 2)
456
+ def descendants_of(class_or_qname, max_depth: nil)
457
+ inheritance_query.descendants(class_or_qname, max_depth: max_depth)
458
+ end
459
+
460
+ # Get associations involving a class.
461
+ #
462
+ # @param class_or_qname [Lutaml::Uml::Class, String] The class object
463
+ # or qualified name string
464
+ # @param options [Hash] Query options
465
+ # @option options [Symbol] :direction (:both) Filter by direction:
466
+ # :source, :target, or :both
467
+ # @option options [Boolean] :owned_only Return only owned associations
468
+ # @option options [Boolean] :navigable_only
469
+ # Return only navigable associations
470
+ # @return [Array<Lutaml::Uml::Association>] Array of association objects
471
+ # @example
472
+ # all_assocs = repo.associations_of("ModelRoot::Building")
473
+ # outgoing = repo.associations_of(
474
+ # "ModelRoot::Building", direction: :source)
475
+ def associations_of(class_or_qname, options = {})
476
+ association_query.find_for_class(class_or_qname, options)
477
+ end
478
+
479
+ # Get diagrams in a specific package.
480
+ #
481
+ # @param package_path [String] The package path or package ID
482
+ # @return [Array<Lutaml::Uml::Diagram>] Array of diagram objects
483
+ # @example
484
+ # diagrams = repo.diagrams_in_package("ModelRoot::i-UR::urf")
485
+ def diagrams_in_package(package_path)
486
+ diagram_query.in_package(package_path)
487
+ end
488
+
489
+ # Find a diagram by its name.
490
+ #
491
+ # @param diagram_name [String] The diagram name
492
+ # @return [Lutaml::Uml::Diagram, nil] The diagram object,
493
+ # or nil if not found
494
+ # @example
495
+ # diagram = repo.find_diagram("Class Diagram 1")
496
+ def find_diagram(diagram_name)
497
+ diagram_query.find_by_name(diagram_name)
498
+ end
499
+
500
+ # Get all diagrams in the model.
501
+ #
502
+ # @return [Array<Lutaml::Uml::Diagram>] Array of all diagram objects
503
+ # @example
504
+ # all_diagrams = repo.all_diagrams
505
+ def all_diagrams
506
+ diagram_query.all
507
+ end
508
+
509
+ # Search for model elements by query string.
510
+ #
511
+ # @param query [String] The search query
512
+ # @param types [Array<Symbol>] Types to search (:class, :attribute,
513
+ # :association) (default: [:class, :attribute, :association])
514
+ # @param fields [Array<Symbol>] Fields to search in
515
+ # (:name, :documentation)
516
+ # (default: [:name])
517
+ # @return [Hash] Search results grouped by type
518
+ # @example
519
+ # results = repo.search("Building")
520
+ # results = repo.search("address", types: [:attribute])
521
+ # results = repo.search("urban", fields: [:name, :documentation])
522
+ def search(
523
+ query, types: %i[class attribute association], fields: [:name]
524
+ )
525
+ search_query.search(query, types: types, fields: fields)
526
+ end
527
+
528
+ # Search for model elements by regex pattern.
529
+ #
530
+ # Similar to search but treats query as a regex pattern. Returns
531
+ # SearchResult objects for consistency with regular search.
532
+ #
533
+ # @param pattern [String, Regexp] The regex pattern to match
534
+ # @param types [Array<Symbol>] Types to search (:class, :attribute,
535
+ # :association) (default: [:class, :attribute, :association])
536
+ # @param fields [Array<Symbol>] Fields to search in
537
+ # (:name, :documentation)
538
+ # (default: [:name])
539
+ # @return [Hash] Search results grouped by type (same format as search)
540
+ # @example
541
+ # results = repo.search("^Building.*", types:[:class])
542
+ # results = repo.search("address$", types: [:attribute])
543
+ # results = repo.search("urban", fields: [:documentation])
544
+ def search( # rubocop:disable Lint/DuplicateMethods
545
+ pattern,
546
+ types: %i[class attribute association],
547
+ fields: [:name]
548
+ )
549
+ search_query.search(pattern, types: types, fields: fields)
550
+ end
551
+
552
+ # Get comprehensive statistics about the repository.
553
+ #
554
+ # Returns detailed metrics including package depths, class complexity,
555
+ # attribute distributions, and model quality metrics.
556
+ # Statistics are calculated once during initialization and cached.
557
+ #
558
+ # @return [Hash] Comprehensive statistics hash
559
+ # @example
560
+ # stats = repo.statistics
561
+ # puts "Total packages: #{stats[:total_packages]}"
562
+ # puts "Max package depth: #{stats[:max_package_depth]}"
563
+ # puts "Most complex class:
564
+ # #{stats[:most_complex_classes].first[:name]}"
565
+ def statistics
566
+ @statistics
567
+ end
568
+
569
+ # Validate the repository for consistency and integrity.
570
+ #
571
+ # Performs comprehensive validation including:
572
+ # - Type reference validation
573
+ # - Generalization reference validation
574
+ # - Circular inheritance detection
575
+ # - Association reference validation
576
+ # - Multiplicity validation
577
+ #
578
+ # @param verbose [Boolean] Collect detailed validation information
579
+ # @return [Validators::ValidationResult] Validation results
580
+ # @example
581
+ # result = repo.validate
582
+ # if result.valid?
583
+ # puts "Repository is valid"
584
+ # else
585
+ # result.errors.each { |error| puts "ERROR: #{error}" }
586
+ # end
587
+ def validate(verbose: false)
588
+ Validators::RepositoryValidator.new(@document,
589
+ @indexes).validate(verbose: verbose)
590
+ end
591
+
592
+ # Build a query using the Query DSL
593
+ #
594
+ # Provides a fluent interface for building complex queries with
595
+ # method chaining, lazy evaluation, and composable filters.
596
+ #
597
+ # @yield [QueryDSL::QueryBuilder] The query builder
598
+ # @return [QueryDSL::QueryBuilder] The query builder for further chaining
599
+ # @example Basic query
600
+ # results = repo.query do |q|
601
+ # q.classes.where(stereotype: 'featureType')
602
+ # end.all
603
+ #
604
+ # @example Complex query
605
+ # results = repo.query do |q|
606
+ # q.classes
607
+ # .in_package('ModelRoot::i-UR', recursive: true)
608
+ # .where { |c| c.attributes&.size.to_i > 10 }
609
+ # .order_by(:name, direction: :desc)
610
+ # .limit(5)
611
+ # end.execute
612
+ def query(&block)
613
+ builder = QueryDSL::QueryBuilder.new(self)
614
+ block&.call(builder)
615
+ builder
616
+ end
617
+
618
+ # Build and execute a query using the Query DSL
619
+ #
620
+ # Same as [`query`](#query) but executes immediately and returns results.
621
+ #
622
+ # @yield [QueryDSL::QueryBuilder] The query builder
623
+ # @return [Array] The query results
624
+ # @example
625
+ # results = repo.query! do |q|
626
+ # q.classes.where(stereotype: 'featureType')
627
+ # end
628
+ def query!(&block)
629
+ query(&block).execute
630
+ end
631
+
632
+ # Convenience methods for SPA data transformer
633
+
634
+ # Get all packages as an array (excluding root Document)
635
+ # @return [Array<Lutaml::Uml::Package>] All packages
636
+ def packages_index
637
+ (@indexes[:package_paths]&.values || []).grep(Lutaml::Uml::Package)
638
+ end
639
+
640
+ # Get all classes (including datatypes and enums) as an array
641
+ # @return [Array] All classifiers
642
+ def classes_index
643
+ @indexes[:qualified_names]&.values || []
644
+ end
645
+
646
+ # Get all associations as an array
647
+ # Collects from both document-level (XMI) and class-level (QEA/EA)
648
+ # @return [Array<Lutaml::Uml::Association>] All associations
649
+ def associations_index # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
650
+ # Use cached index if available (built by IndexBuilder)
651
+ return @indexes[:associations].values if @indexes[:associations]
652
+
653
+ # Fallback for edge cases: collect from document and classes
654
+ associations = []
655
+
656
+ # Document-level associations (XMI format)
657
+ associations.concat(@document.associations) if @document.associations
658
+
659
+ # Class-level associations (QEA/EA format)
660
+ classes_index.each do |klass|
661
+ next unless klass.respond_to?(:associations) && klass.associations
662
+
663
+ klass.associations.each do |assoc|
664
+ # Avoid duplicates - check xmi_id
665
+ next if associations.any? { |a| a.xmi_id == assoc.xmi_id }
666
+
667
+ associations << assoc
668
+ end
669
+ end
670
+
671
+ associations
672
+ end
673
+
674
+ # Get qualified name(key) by the object from @indexes[:qualified_names]
675
+ def qualified_name_for(obj)
676
+ @indexes[:qualified_names].key(obj)
677
+ end
678
+
679
+ # Get all diagrams as an array
680
+ # @return [Array<Lutaml::Uml::Diagram>] All diagrams
681
+ def diagrams_index
682
+ all_diagrams
683
+ end
684
+
685
+ # Get all classes in the repository
686
+ # @return [Array] All class objects (classes, datatypes, enums)
687
+ # @example
688
+ # all = repo.all_classes
689
+ def all_classes
690
+ classes_index
691
+ end
692
+
693
+ # DEPRECATED: Use search with types: [:class] instead
694
+ # @deprecated Use {#search} with types filter
695
+ def search_classes(query_string)
696
+ search(query_string, types: [:class])[:classes]
697
+ end
698
+
699
+ # DEPRECATED: Use subtypes_of instead
700
+ # @deprecated Use {#subtypes_of}
701
+ def find_children(class_or_qname, recursive: false)
702
+ subtypes_of(class_or_qname, recursive: recursive)
703
+ end
704
+
705
+ # DEPRECATED: Use associations_of instead
706
+ # @deprecated Use {#associations_of}
707
+ def find_associations(class_or_qname, options = {})
708
+ associations_of(class_or_qname, options)
709
+ end
710
+
711
+ # DEPRECATED: Use diagrams_in_package or all_diagrams instead
712
+ # @deprecated Use {#diagrams_in_package} or {#all_diagrams}
713
+ def find_diagrams(package_path)
714
+ diagrams_in_package(package_path)
715
+ end
716
+
717
+ # DEPRECATED: Use export_to_package instead
718
+ # @deprecated Use {#export_to_package}
719
+ def export(output_path, options = {})
720
+ export_to_package(output_path, options)
721
+ end
722
+
723
+ # Custom marshaling to exclude runtime-only query objects
724
+ #
725
+ # Only serializes the core data (document, indexes, and metadata), not the
726
+ # derived query service objects. This keeps serialized size minimal.
727
+ #
728
+ # @return [Hash] Serializable state (document, indexes, and metadata)
729
+ # @api private
730
+ def marshal_dump
731
+ { document: @document, indexes: @indexes, metadata: @metadata }
732
+ end
733
+
734
+ # Restore from marshaled state
735
+ #
736
+ # Reconstructs the repository from serialized document, indexes,
737
+ # and metadata,
738
+ # reinitializing all query services.
739
+ #
740
+ # @param data [Hash] Serialized state with :document, :indexes,
741
+ # and :metadata
742
+ # @return [void]
743
+ # @api private
744
+ def marshal_load(data) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
745
+ @document = data[:document]
746
+ @indexes = data[:indexes]
747
+ @metadata = data[:metadata]
748
+
749
+ # Reinitialize runtime query services
750
+ @package_query = Queries::PackageQuery.new(@document, @indexes)
751
+ @class_query = Queries::ClassQuery.new(@document, @indexes)
752
+ @inheritance_query = Queries::InheritanceQuery.new(@document, @indexes)
753
+ @association_query = Queries::AssociationQuery.new(@document, @indexes)
754
+ @diagram_query = Queries::DiagramQuery.new(@document, @indexes)
755
+ @search_query = Queries::SearchQuery.new(@document, @indexes)
756
+
757
+ # Reinitialize helpers and cache statistics
758
+ @statistics_calculator = StatisticsCalculator.new(@document, @indexes)
759
+ @statistics = @statistics_calculator.calculate.freeze
760
+ @error_handler = ErrorHandler.new(self)
761
+
762
+ freeze
763
+ end
764
+
765
+ private
766
+
767
+ # Get package query service
768
+ #
769
+ # @return [Queries::PackageQuery] The package query service
770
+ attr_reader :package_query
771
+
772
+ # Get class query service
773
+ #
774
+ # @return [Queries::ClassQuery] The class query service
775
+ attr_reader :class_query
776
+
777
+ # Get inheritance query service
778
+ #
779
+ # @return [Queries::InheritanceQuery] The inheritance query service
780
+ attr_reader :inheritance_query
781
+
782
+ # Get association query service
783
+ #
784
+ # @return [Queries::AssociationQuery] The association query service
785
+ attr_reader :association_query
786
+
787
+ # Get diagram query service
788
+ #
789
+ # @return [Queries::DiagramQuery] The diagram query service
790
+ attr_reader :diagram_query
791
+
792
+ # Get search query service
793
+ #
794
+ # @return [Queries::SearchQuery] The search query service
795
+ attr_reader :search_query
796
+ end
797
+ end
798
+ end