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,508 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "element_presenter"
4
+ require_relative "../../ea/diagram/svg_renderer"
5
+ require_relative "../../ea/diagram/layout_engine"
6
+ require_relative "../../ea/diagram/style_resolver"
7
+
8
+ module Lutaml
9
+ module UmlRepository
10
+ module Presenters
11
+ # Presenter for UML Diagram elements
12
+ #
13
+ # Coordinates the entire diagram rendering pipeline by:
14
+ # 1. Loading elements and connectors from the repository
15
+ # 2. Converting EA coordinates to SVG format
16
+ # 3. Using StyleResolver to merge EA data + config + defaults
17
+ # 4. Creating a DiagramRenderer wrapper
18
+ # 5. Generating SVG output via SvgRenderer
19
+ class DiagramPresenter < ElementPresenter
20
+ attr_reader :config_path
21
+
22
+ # @param diagram [Lutaml::Uml::Diagram] The diagram to present
23
+ # @param repository [Repository] Repository for looking up elements
24
+ # @param options [Hash] Rendering options
25
+ # @option options [String] :config_path Path to diagram configuration
26
+ def initialize(diagram, repository, options = {})
27
+ super(diagram, repository)
28
+ @config_path = options[:config_path]
29
+ @layout_engine = Ea::Diagram::LayoutEngine.new
30
+ end
31
+
32
+ # Generate SVG output for the diagram
33
+ #
34
+ # @param options [Hash] Rendering options
35
+ # @option options [Integer] :padding (20) Padding around diagram
36
+ # @option options [String] :background_color ("#ffffff")
37
+ # Background color
38
+ # @option options [Boolean] :grid_visible (false) Show grid
39
+ # @option options [Boolean] :interactive (false)
40
+ # Enable interactive features
41
+ # @return [String] Complete SVG content
42
+ def svg_output(options = {}) # rubocop:disable Metrics/MethodLength
43
+ # Build diagram data structure
44
+ diagram_data = {
45
+ name: element.name,
46
+ elements: build_elements_data,
47
+ connectors: build_connectors_data,
48
+ }
49
+
50
+ # Create diagram renderer wrapper
51
+ diagram_renderer = DiagramRendererWrapper.new(diagram_data,
52
+ @layout_engine)
53
+
54
+ # Create SVG renderer with configuration
55
+ renderer_options = options.merge(config_path: config_path)
56
+ svg_renderer = Ea::Diagram::SvgRenderer.new(diagram_renderer,
57
+ renderer_options)
58
+
59
+ # Generate and return SVG
60
+ svg_renderer.render
61
+ end
62
+
63
+ # Get elements in the diagram
64
+ #
65
+ # @return [Array<Hash>] Array of element data hashes
66
+ def elements
67
+ build_elements_data
68
+ end
69
+
70
+ # Get connectors in the diagram
71
+ #
72
+ # @return [Array<Hash>] Array of connector data hashes
73
+ def connectors
74
+ build_connectors_data
75
+ end
76
+
77
+ # Text output for diagram
78
+ def to_text # rubocop:disable Metrics/AbcSize
79
+ lines = []
80
+ lines << "Diagram: #{element.name}"
81
+ lines << ("=" * 50)
82
+ lines << ""
83
+ lines << "Type: #{element.diagram_type}"
84
+ lines << "Package: #{element.package_name || 'Unknown'}"
85
+ lines << "Elements: #{(element.diagram_objects || []).count}"
86
+ lines << "Connectors: #{(element.diagram_links || []).count}"
87
+ lines.join("\n")
88
+ end
89
+
90
+ # Table row for diagram
91
+ def to_table_row
92
+ {
93
+ type: "Diagram",
94
+ name: element.name || "(unnamed)",
95
+ details: "#{element.diagram_type} " \
96
+ "- #{(element.diagram_objects || []).count} elements",
97
+ }
98
+ end
99
+
100
+ # Hash representation
101
+ def to_hash
102
+ {
103
+ type: "Diagram",
104
+ name: element.name,
105
+ diagram_type: element.diagram_type,
106
+ package_name: element.package_name,
107
+ elements_count: (element.diagram_objects || []).count,
108
+ connectors_count: (element.diagram_links || []).count,
109
+ }
110
+ end
111
+
112
+ private
113
+
114
+ # Build element data from diagram_objects
115
+ #
116
+ # @return [Array<Hash>] Array of element data for rendering
117
+ def build_elements_data # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
118
+ return [] unless element.diagram_objects
119
+
120
+ element.diagram_objects.filter_map do |diagram_object|
121
+ # Look up the actual element in the repository
122
+ uml_element = find_element_by_xmi_id(diagram_object.object_xmi_id)
123
+ next nil unless uml_element
124
+
125
+ # Convert EA coordinates to SVG format
126
+ coords = @layout_engine.convert_ea_coordinates(diagram_object)
127
+
128
+ # Build element data hash
129
+ {
130
+ id: diagram_object.object_xmi_id,
131
+ name: uml_element.name,
132
+ type: determine_element_type(uml_element),
133
+ x: coords[:x],
134
+ y: coords[:y],
135
+ width: coords[:width],
136
+ height: coords[:height],
137
+ stereotype: extract_stereotype(uml_element),
138
+ attributes: extract_attributes(uml_element),
139
+ operations: extract_operations(uml_element),
140
+ element: uml_element, # Original UML element
141
+ diagram_object: diagram_object, # Original diagram placement data
142
+ }
143
+ end
144
+ end
145
+
146
+ # Build connector data from diagram_links
147
+ #
148
+ # @return [Array<Hash>] Array of connector data for rendering
149
+ def build_connectors_data # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
150
+ return [] unless element.diagram_links
151
+
152
+ # Build elements index for quick lookup by XMI ID
153
+ elements_map = build_elements_data
154
+ .to_h do |elem|
155
+ [elem[:id], elem]
156
+ end
157
+
158
+ # Build diagram objects map for EA internal ID lookup
159
+ diagram_objects_map = {}
160
+ element.diagram_objects&.each do |dobj|
161
+ diagram_objects_map[extract_ea_id(dobj)] = dobj.object_xmi_id
162
+ end
163
+
164
+ element.diagram_links.filter_map do |diagram_link| # rubocop:disable Metrics/BlockLength
165
+ # Skip hidden connectors
166
+ next nil if diagram_link.hidden
167
+
168
+ # Look up the actual connector in the repository
169
+ connector = find_connector_by_xmi_id(diagram_link.connector_xmi_id)
170
+
171
+ # Even if connector object not found, we can still render
172
+ # Original diagram routing datausing geometry
173
+ # The diagram_link contains all visual information needed
174
+ connector_type = if connector
175
+ determine_connector_type(connector)
176
+ else
177
+ # Default to association if connector object
178
+ # not found
179
+ "association"
180
+ end
181
+
182
+ # Parse source and target from diagram_link style
183
+ # (contains SOID/EOID)
184
+ style_data = parse_diagram_link_style(diagram_link.style)
185
+
186
+ source_elem = nil
187
+ target_elem = nil
188
+
189
+ # Try to find elements using EA internal IDs from style
190
+ if style_data[:soid]
191
+ source_xmi_id = diagram_objects_map[style_data[:soid]]
192
+ source_elem = elements_map[source_xmi_id] if source_xmi_id
193
+ end
194
+
195
+ if style_data[:eoid]
196
+ target_xmi_id = diagram_objects_map[style_data[:eoid]]
197
+ target_elem = elements_map[target_xmi_id] if target_xmi_id
198
+ end
199
+
200
+ # Fallback: try to find from connector object
201
+ # if style parsing failed
202
+ if (!source_elem || !target_elem) && connector
203
+ source_elem ||= find_connector_source(connector, elements_map)
204
+ target_elem ||= find_connector_target(connector, elements_map)
205
+ end
206
+
207
+ # Build connector data hash
208
+ {
209
+ id: diagram_link.connector_xmi_id,
210
+ type: connector_type,
211
+ geometry: diagram_link.geometry,
212
+ style: diagram_link.style,
213
+ # Source element for geometry calculation
214
+ source_element: source_elem,
215
+ # Target element for geometry calculation
216
+ target_element: target_elem,
217
+ # May be nil if not found
218
+ element: connector,
219
+ # Original diagram routing data
220
+ diagram_link: diagram_link,
221
+ }
222
+ end
223
+ end
224
+
225
+ # Parse EA diagram link style string
226
+ #
227
+ # Style format: "Mode=3;EOID=82C649C4;SOID=21096985;
228
+ # Color=-1;LWidth=2;TREE=V;"
229
+ # SOID = Source Object ID (EA internal ID)
230
+ # EOID = End Object ID (EA internal ID)
231
+ #
232
+ # @param style_string [String] EA style string
233
+ # @return [Hash] Parsed style data
234
+ def parse_diagram_link_style(style_string) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
235
+ return {} unless style_string
236
+
237
+ data = {}
238
+ style_string.split(";").each do |pair|
239
+ next if pair.empty?
240
+
241
+ key, value = pair.split("=", 2)
242
+ next unless key && value
243
+
244
+ case key.strip
245
+ when "SOID"
246
+ data[:soid] = value.strip
247
+ when "EOID"
248
+ data[:eoid] = value.strip
249
+ end
250
+ end
251
+ data
252
+ end
253
+
254
+ # Extract EA internal ID from diagram object
255
+ #
256
+ # @param diagram_object [Object] Diagram object
257
+ # @return [String, nil] EA internal ID (DUID from style)
258
+ def extract_ea_id(diagram_object)
259
+ # EA stores the internal ID as DUID in the style string
260
+ unless diagram_object.respond_to?(:style) && diagram_object.style
261
+ return nil
262
+ end
263
+
264
+ # Parse DUID from style string
265
+ # Style format: "NSL=0;LCol=-1;...;DUID=82C649C4;BCol=16764159;..."
266
+ style = diagram_object.style
267
+ match = style.match(/DUID=([^;]+)/)
268
+ return match[1] if match
269
+
270
+ nil
271
+ end
272
+
273
+ # Find element in repository by XMI ID
274
+ #
275
+ # @param xmi_id [String] XMI identifier
276
+ # @return [Object, nil] UML element or nil if not found
277
+ def find_element_by_xmi_id(xmi_id)
278
+ return nil unless xmi_id && repository
279
+
280
+ # Try to find in classes index (includes classes, datatypes, enums)
281
+ element = repository.classes_index.find { |cls| cls.xmi_id == xmi_id }
282
+ return element if element
283
+
284
+ # Try to find in packages index
285
+ repository.packages_index.find { |pkg| pkg.xmi_id == xmi_id }
286
+ end
287
+
288
+ # Find connector in repository by XMI ID
289
+ #
290
+ # @param xmi_id [String] XMI identifier
291
+ # @return [Object, nil] UML connector or nil if not found
292
+ def find_connector_by_xmi_id(xmi_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
293
+ return nil unless xmi_id && repository
294
+
295
+ # Look in document-level associations index
296
+ connector = repository.associations_index.find do |assoc|
297
+ assoc.xmi_id == xmi_id
298
+ end
299
+
300
+ return connector if connector
301
+
302
+ repository.classes_index.each do |klass|
303
+ if klass.respond_to?(:generalization) && klass.generalization
304
+ # Look in class-level generalizations
305
+ gen = klass.generalization
306
+
307
+ # Handle both single generalization and array of generalizations
308
+ generalizations = gen.is_a?(Array) ? gen : [gen]
309
+
310
+ generalizations.each do |g|
311
+ return g if g.respond_to?(:xmi_id) && g.xmi_id == xmi_id
312
+ end
313
+ elsif klass.respond_to?(:associations) && klass.associations
314
+ # Look in class-level associations
315
+ assoc = klass.associations.find do |a|
316
+ a.respond_to?(:xmi_id) && a.xmi_id == xmi_id
317
+ end
318
+ return assoc if assoc
319
+ end
320
+ end
321
+
322
+ nil
323
+ end
324
+
325
+ # Find connector target element
326
+ #
327
+ # @param connector [Object] UML connector
328
+ # @param elements_map [Hash] Map of element ID to element data
329
+ # @return [Hash, nil] Target element data
330
+ def find_connector_target(connector, elements_map) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
331
+ target_id = nil
332
+
333
+ if connector.respond_to?(:target) && connector.target
334
+ target_id = connector.target
335
+ elsif connector.respond_to?(:supplier) && connector.supplier
336
+ target_id = connector.supplier
337
+ elsif connector.respond_to?(:general) && connector.general
338
+ target_id = connector.general
339
+ elsif connector.respond_to?(:member_end) && connector.member_end
340
+ # For associations, use the second member_end
341
+ ends = if connector.member_end.is_a?(Array)
342
+ connector.member_end
343
+ else
344
+ [connector.member_end]
345
+ end
346
+ if ends.size > 1
347
+ target_id = ends[1]
348
+ end
349
+ end
350
+
351
+ elements_map[target_id]
352
+ end
353
+
354
+ # Find connector source element
355
+ #
356
+ # @param connector [Object] UML connector
357
+ # @param elements_map [Hash] Map of element ID to element data
358
+ # @return [Hash, nil] Source element data
359
+ def find_connector_source(connector, elements_map) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
360
+ source_id = nil
361
+
362
+ if connector.respond_to?(:source) && connector.source
363
+ source_id = connector.source
364
+ elsif connector.respond_to?(:client) && connector.client
365
+ source_id = connector.client
366
+ elsif connector.respond_to?(:specific) && connector.specific
367
+ source_id = connector.specific
368
+ elsif connector.respond_to?(:owner_end) && connector.owner_end
369
+ source_id = connector.owner_end
370
+ elsif connector.respond_to?(:member_end) && connector.member_end
371
+ # For associations, use the first member_end
372
+ ends = if connector.member_end.is_a?(Array)
373
+ connector.member_end
374
+ else
375
+ [connector.member_end]
376
+ end
377
+ if ends.any?
378
+ source_id = ends[0]
379
+ end
380
+ end
381
+
382
+ elements_map[source_id]
383
+ end
384
+
385
+ # Determine element type for rendering
386
+ #
387
+ # @param uml_element [Object] UML element
388
+ # @return [String] Element type
389
+ def determine_element_type(uml_element)
390
+ case uml_element.class.name
391
+ when /DataType/
392
+ "datatype"
393
+ when /Enum/
394
+ "enum"
395
+ when /Package/
396
+ "package"
397
+ else
398
+ "class"
399
+ end
400
+ end
401
+
402
+ # Determine connector type for rendering
403
+ #
404
+ # @param connector [Object] UML connector
405
+ # @return [String] Connector type
406
+ def determine_connector_type(connector)
407
+ case connector.class.name
408
+ when /Generalization/
409
+ "generalization"
410
+ when /Dependency/
411
+ "dependency"
412
+ when /Realization/
413
+ "realization"
414
+ else
415
+ "association"
416
+ end
417
+ end
418
+
419
+ # Extract stereotype from element
420
+ #
421
+ # @param uml_element [Object] UML element
422
+ # @return [String, nil] Stereotype name
423
+ def extract_stereotype(uml_element)
424
+ return nil unless uml_element.respond_to?(:stereotype)
425
+
426
+ stereotype = uml_element.stereotype
427
+ return nil unless stereotype
428
+
429
+ # Handle array of stereotypes
430
+ if stereotype.is_a?(Array)
431
+ stereotype.first
432
+ else
433
+ stereotype
434
+ end
435
+ end
436
+
437
+ # Extract attributes from element
438
+ #
439
+ # @param uml_element [Object] UML element
440
+ # @return [Array<Hash>] Array of attribute data
441
+ def extract_attributes(uml_element)
442
+ return [] unless uml_element.respond_to?(:attributes)
443
+ return [] unless uml_element.attributes
444
+
445
+ uml_element.attributes.map do |attr|
446
+ {
447
+ name: attr.name,
448
+ type: attr.type,
449
+ visibility: attr.respond_to?(:visibility) ? attr.visibility : nil,
450
+ }
451
+ end
452
+ end
453
+
454
+ # Extract operations from element
455
+ #
456
+ # @param uml_element [Object] UML element
457
+ # @return [Array<Hash>] Array of operation data
458
+ def extract_operations(uml_element)
459
+ return [] unless uml_element.respond_to?(:operations)
460
+ return [] unless uml_element.operations
461
+
462
+ uml_element.operations.map do |op|
463
+ {
464
+ name: op.name,
465
+ visibility: op.respond_to?(:visibility) ? op.visibility : nil,
466
+ return_type: op.respond_to?(:return_type) ? op.return_type : nil,
467
+ parameters: extract_parameters(op),
468
+ }
469
+ end
470
+ end
471
+
472
+ # Extract parameters from operation
473
+ #
474
+ # @param operation [Object] UML operation
475
+ # @return [Array<Hash>] Array of parameter data
476
+ def extract_parameters(operation)
477
+ return [] unless operation.respond_to?(:owned_parameter)
478
+ return [] unless operation.owned_parameter
479
+
480
+ operation.owned_parameter.map do |param|
481
+ {
482
+ name: param.name,
483
+ type: param.type,
484
+ }
485
+ end
486
+ end
487
+
488
+ # Wrapper class to adapt diagram data to SvgRenderer expectations
489
+ class DiagramRendererWrapper
490
+ attr_reader :diagram_data, :bounds, :elements, :connectors
491
+
492
+ def initialize(diagram_data, layout_engine)
493
+ @diagram_data = diagram_data
494
+ @elements = diagram_data[:elements] || []
495
+ @connectors = diagram_data[:connectors] || []
496
+ @bounds = layout_engine.calculate_bounds(diagram_data)
497
+ end
498
+ end
499
+ end
500
+
501
+ # Register with factory
502
+ PresenterFactory.register(
503
+ Lutaml::Uml::Diagram,
504
+ DiagramPresenter,
505
+ )
506
+ end
507
+ end
508
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lutaml
4
+ module UmlRepository
5
+ module Presenters
6
+ # Abstract base class for presenting UML elements.
7
+ #
8
+ # Defines the common interface that all element presenters must
9
+ # implement. Provides shared utility methods for formatting.
10
+ #
11
+ # Subclasses must implement: to_text, to_table_row, to_hash
12
+ class ElementPresenter
13
+ attr_reader :element, :repository, :context
14
+
15
+ # @param element [Object] The UML element to present
16
+ # @param repository [UmlRepository, nil] Optional repository for
17
+ # additional context
18
+ # @param context [Hash, nil] Optional context hash
19
+ def initialize(element, repository = nil, context = nil)
20
+ @element = element
21
+ @repository = repository
22
+ @context = context || {}
23
+ end
24
+
25
+ protected
26
+
27
+ # Generate detailed text view of the element.
28
+ #
29
+ # @return [String] Formatted text representation
30
+ # @raise [NotImplementedError] if not implemented by subclass
31
+ def to_text
32
+ raise NotImplementedError,
33
+ "#{self.class} must implement #to_text"
34
+ end
35
+
36
+ # Generate a single row for table display.
37
+ #
38
+ # @return [Hash] Hash with keys: :type, :name, :details, etc.
39
+ # @raise [NotImplementedError] if not implemented by subclass
40
+ def to_table_row
41
+ raise NotImplementedError,
42
+ "#{self.class} must implement #to_table_row"
43
+ end
44
+
45
+ # Generate structured hash for JSON/YAML output.
46
+ #
47
+ # @return [Hash] Structured data representation
48
+ # @raise [NotImplementedError] if not implemented by subclass
49
+ def to_hash
50
+ raise NotImplementedError,
51
+ "#{self.class} must implement #to_hash"
52
+ end
53
+
54
+ # Format cardinality for display.
55
+ #
56
+ # @param attr [Object] Attribute or property with cardinality
57
+ # @return [String] Formatted cardinality like "[1..1]" or "[0..*]"
58
+ def format_cardinality(attr) # rubocop:disable Metrics/CyclomaticComplexity
59
+ return "" unless attr.respond_to?(:cardinality) &&
60
+ attr.cardinality
61
+
62
+ card = attr.cardinality
63
+ min = card.respond_to?(:min) ? (card.min || "0") : "0"
64
+ max = card.respond_to?(:max) ? (card.max || "*") : "*"
65
+
66
+ "[#{min}..#{max}]"
67
+ end
68
+
69
+ # Truncate text to maximum length.
70
+ #
71
+ # @param text [String, nil] Text to truncate
72
+ # @param max_length [Integer] Maximum length
73
+ # @return [String] Truncated text with "..." if needed
74
+ def truncate(text, max_length = 50)
75
+ return "" if text.nil?
76
+ return text if text.length <= max_length
77
+
78
+ "#{text[0...(max_length - 3)]}..."
79
+ end
80
+
81
+ # Extract package path from qualified name.
82
+ #
83
+ # @param qualified_name [String] Fully qualified name
84
+ # @return [String] Package path (everything except last component)
85
+ def extract_package_path(qualified_name)
86
+ parts = qualified_name.to_s.split("::")
87
+ parts[0..-2].join("::")
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "element_presenter"
4
+ require_relative "presenter_factory"
5
+
6
+ module Lutaml
7
+ module UmlRepository
8
+ module Presenters
9
+ # Presenter for UML Enumeration elements.
10
+ #
11
+ # Formats enumeration information including literal values.
12
+ class EnumPresenter < ElementPresenter
13
+ def initialize(element, repository = nil, context = nil)
14
+ super
15
+ end
16
+
17
+ def to_text # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
18
+ lines = []
19
+ lines << "Enumeration: #{element.name}"
20
+ lines << ("=" * 50)
21
+ lines << ""
22
+ lines << "Name: #{element.name}"
23
+ if element.respond_to?(:xmi_id) && element.xmi_id
24
+ lines << "XMI ID: #{element.xmi_id}"
25
+ end
26
+ if element.respond_to?(:stereotype) && element.stereotype
27
+ lines << "Stereotype: #{element.stereotype}"
28
+ end
29
+ if element.respond_to?(:visibility) && element.visibility
30
+ lines << "Visibility: #{element.visibility}"
31
+ end
32
+ lines << ""
33
+
34
+ if element.values && !element.values.empty?
35
+ lines << "Literal Values (#{element.values.size}):"
36
+ element.each_value do |value|
37
+ lines << " - #{value.name || value.to_s}"
38
+ end
39
+ else
40
+ lines << "Literal Values: (none)"
41
+ end
42
+
43
+ lines.join("\n")
44
+ end
45
+
46
+ def to_table_row
47
+ value_count = element.values ? element.values.size : 0
48
+ {
49
+ type: "Enumeration",
50
+ name: element.name || "(unnamed)",
51
+ details: "#{value_count} literal value(s)",
52
+ }
53
+ end
54
+
55
+ def to_hash # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
56
+ data = {
57
+ type: "Enumeration",
58
+ name: element.name,
59
+ value_count: element.values ? element.values.size : 0,
60
+ }
61
+
62
+ data[:xmi_id] = element.xmi_id if
63
+ element.respond_to?(:xmi_id) && element.xmi_id
64
+ data[:stereotype] = element.stereotype if
65
+ element.respond_to?(:stereotype) && element.stereotype
66
+ data[:visibility] = element.visibility if
67
+ element.respond_to?(:visibility) && element.visibility
68
+
69
+ if element.values && !element.values.empty?
70
+ data[:values] = element.values.map do |v|
71
+ v.respond_to?(:name) ? v.name : v.to_s
72
+ end
73
+ end
74
+
75
+ data
76
+ end
77
+ end
78
+
79
+ # Register with factory
80
+ PresenterFactory.register(Lutaml::Uml::Enum, EnumPresenter)
81
+ end
82
+ end
83
+ end