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,225 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_transformer"
4
+ require_relative "tagged_value_transformer"
5
+ require_relative "instance_transformer"
6
+ require_relative "enum_transformer"
7
+ require_relative "data_type_transformer"
8
+ require "lutaml/uml"
9
+
10
+ module Lutaml
11
+ module Qea
12
+ module Factory
13
+ # Transforms EA packages to UML packages
14
+ class PackageTransformer < BaseTransformer
15
+ # Transform EA package to UML package
16
+ # @param ea_package [EaPackage] EA package model
17
+ # @return [Lutaml::Uml::Package] UML package
18
+ def transform(ea_package) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
19
+ return nil if ea_package.nil?
20
+
21
+ Lutaml::Uml::Package.new.tap do |pkg|
22
+ # Map basic properties
23
+ pkg.name = ea_package.name
24
+ pkg.xmi_id = normalize_guid_to_xmi_format(ea_package.ea_guid,
25
+ "EAPK")
26
+
27
+ # Map definition/notes
28
+ pkg.definition = ea_package.notes unless
29
+ ea_package.notes.nil? || ea_package.notes.empty?
30
+
31
+ # Load and transform tagged values
32
+ # TODO: Fix tagged_values assignment - temporarily commented out
33
+ # pkg.tagged_values = load_tagged_values(ea_package.ea_guid)
34
+
35
+ # Load stereotype from t_xref
36
+ stereotype = load_stereotype(ea_package.ea_guid)
37
+ pkg.stereotype = [stereotype] if stereotype
38
+
39
+ # Note: Child packages and contents will be loaded separately
40
+ # to avoid circular dependencies and allow lazy loading
41
+ # Don't initialize collections - they have default values
42
+ end
43
+ end
44
+
45
+ # Transform and build complete package hierarchy
46
+ # @param ea_package [EaPackage] Root EA package
47
+ # @param include_children [Boolean] Whether to recursively load children
48
+ # @return [Lutaml::Uml::Package] Complete UML package with hierarchy
49
+ def transform_with_hierarchy(ea_package, include_children: true)
50
+ pkg = transform(ea_package)
51
+ return pkg unless include_children
52
+
53
+ # Load child packages
54
+ child_packages = load_child_packages(ea_package.package_id)
55
+ pkg.packages = child_packages.map do |child_pkg|
56
+ transform_with_hierarchy(child_pkg, include_children: true)
57
+ end
58
+
59
+ # Load package contents (classes, diagrams, etc.)
60
+ load_package_contents(pkg, ea_package.package_id)
61
+
62
+ pkg
63
+ end
64
+
65
+ private
66
+
67
+ # Load child packages
68
+ # @param parent_id [Integer] Parent package ID
69
+ # @return [Array<EaPackage>] Child packages
70
+ def load_child_packages(parent_id)
71
+ return [] if parent_id.nil?
72
+
73
+ query = "SELECT * FROM t_package WHERE Parent_ID = ? " \
74
+ "ORDER BY TPos"
75
+ rows = database.connection.execute(query, parent_id)
76
+
77
+ rows.map { |row| Models::EaPackage.from_db_row(row) }
78
+ end
79
+
80
+ # Load package contents (objects and diagrams)
81
+ # @param pkg [Lutaml::Uml::Package] UML package to populate
82
+ # @param package_id [Integer] EA package ID
83
+ def load_package_contents(pkg, package_id)
84
+ return if package_id.nil?
85
+
86
+ # Load objects (classes, etc.) in this package
87
+ load_package_objects(pkg, package_id)
88
+
89
+ # Load diagrams in this package
90
+ load_package_diagrams(pkg, package_id)
91
+ end
92
+
93
+ # Load objects for a package
94
+ # @param pkg [Lutaml::Uml::Package] UML package
95
+ # @param package_id [Integer] Package ID
96
+ def load_package_objects(pkg, package_id) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
97
+ query = "SELECT * FROM t_object WHERE Package_ID = ?"
98
+ rows = database.connection.execute(query, package_id)
99
+
100
+ ea_objects = rows.map { |row| Models::EaObject.from_db_row(row) }
101
+
102
+ class_transformer = ClassTransformer.new(database)
103
+ enum_transformer = EnumTransformer.new(database)
104
+ data_type_transformer = DataTypeTransformer.new(database)
105
+ instance_transformer = InstanceTransformer.new(database)
106
+
107
+ ea_objects.each do |ea_obj|
108
+ if enum_object?(ea_obj)
109
+ uml_enum = enum_transformer.transform(ea_obj)
110
+ pkg.enums << uml_enum if uml_enum
111
+ elsif data_type_object?(ea_obj)
112
+ uml_dt = data_type_transformer.transform(ea_obj)
113
+ pkg.data_types << uml_dt if uml_dt
114
+ elsif class_object?(ea_obj)
115
+ uml_class = class_transformer.transform(ea_obj)
116
+ pkg.classes << uml_class if uml_class
117
+ elsif ea_obj.instance?
118
+ uml_instance = instance_transformer.transform(ea_obj)
119
+ pkg.instances << uml_instance if uml_instance
120
+ end
121
+ end
122
+ end
123
+
124
+ # Check if an EA object should be classified as an enum.
125
+ # EA stores enums as either object_type="Enumeration" or
126
+ # object_type="Class" with stereotype="enumeration".
127
+ def enum_object?(ea_obj)
128
+ ea_obj.enumeration? || stereotype_is?(ea_obj, "enumeration")
129
+ end
130
+
131
+ # Check if an EA object should be classified as a data type.
132
+ def data_type_object?(ea_obj)
133
+ ea_obj.data_type?
134
+ end
135
+
136
+ # Check if an EA object should be classified as a class.
137
+ def class_object?(ea_obj)
138
+ return false if enum_object?(ea_obj) || data_type_object?(ea_obj)
139
+
140
+ ea_obj.uml_class? || ea_obj.interface? ||
141
+ ea_obj.object_type == "Text" ||
142
+ ea_obj.object_type == "ProxyConnector"
143
+ end
144
+
145
+ # Check if an object's stereotype matches (case-insensitive).
146
+ def stereotype_is?(ea_obj, expected)
147
+ return false unless ea_obj.stereotype
148
+
149
+ ea_obj.stereotype.downcase == expected
150
+ end
151
+
152
+ # Load diagrams for a package
153
+ # @param pkg [Lutaml::Uml::Package] UML package
154
+ # @param package_id [Integer] Package ID
155
+ def load_package_diagrams(pkg, package_id)
156
+ diagram_transformer = DiagramTransformer.new(database)
157
+
158
+ query = "SELECT * FROM t_diagram WHERE Package_ID = ?"
159
+ rows = database.connection.execute(query, package_id)
160
+
161
+ ea_diagrams = rows.map { |row| Models::EaDiagram.from_db_row(row) }
162
+ pkg.diagrams = diagram_transformer.transform_collection(ea_diagrams)
163
+ end
164
+
165
+ # Load and transform tagged values for a package
166
+ # @param ea_guid [String] Element GUID
167
+ # @return [Array<Lutaml::Uml::TaggedValue>] UML tagged values
168
+ def load_tagged_values(ea_guid)
169
+ return [] if ea_guid.nil?
170
+ return [] unless database.tagged_values
171
+
172
+ # Filter tagged values for this element from the in-memory collection
173
+ ea_tags = database.tagged_values.select do |tag|
174
+ tag.element_id == ea_guid
175
+ end
176
+
177
+ # Transform to UML tagged values
178
+ tag_transformer = TaggedValueTransformer.new(database)
179
+ tag_transformer.transform_collection(ea_tags)
180
+ end
181
+
182
+ # Load stereotype from t_xref table
183
+ # @param ea_guid [String] Element GUID
184
+ # @return [String, nil] Stereotype value (as string to match XMI format)
185
+ def load_stereotype(ea_guid) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
186
+ return nil if ea_guid.nil?
187
+ return nil unless database.xrefs
188
+
189
+ # Find stereotype xref from the in-memory collection
190
+ xref = database.xrefs.find do |x|
191
+ x.client == ea_guid &&
192
+ x.name == "Stereotypes" && x.type == "element property"
193
+ end
194
+
195
+ return nil unless xref
196
+
197
+ # Parse stereotype from Description field
198
+ # Format: @STEREO;Name=ApplicationSchema;FQName=GML::ApplicationSchema;@ENDSTEREO;
199
+ description = xref.description
200
+ return nil if description.nil? || description.empty?
201
+
202
+ # Extract the Name value from the @STEREO format
203
+ if description =~ /@STEREO;Name=([^;]+);/
204
+ return $1
205
+ end
206
+
207
+ nil
208
+ end
209
+
210
+ # Check if an object appears on any diagram
211
+ # @param object_id [Integer] Object ID
212
+ # @return [Boolean] True if object appears on a diagram
213
+ def appears_on_diagram?(object_id)
214
+ return false if object_id.nil?
215
+ return false unless database.diagram_objects
216
+
217
+ # Check if object appears in any diagram's objects
218
+ database.diagram_objects.any? do |dobj|
219
+ dobj.ea_object_id == object_id
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lutaml
4
+ module Qea
5
+ module Factory
6
+ # Resolves references between EA and UML elements
7
+ # Maps EA GUIDs to UML xmi_ids and maintains object relationships
8
+ class ReferenceResolver
9
+ # Initialize empty resolver
10
+ def initialize
11
+ @guid_to_element = {}
12
+ @object_id_to_name = {}
13
+ end
14
+
15
+ # Register EA GUID to UML element mapping
16
+ # @param ea_guid [String] EA GUID
17
+ # @param uml_element [Object] UML element with xmi_id
18
+ # @return [void]
19
+ def register(ea_guid, uml_element)
20
+ return if ea_guid.nil? || uml_element.nil?
21
+
22
+ @guid_to_element[normalize_guid(ea_guid)] = uml_element
23
+ end
24
+
25
+ # Register object ID to name mapping
26
+ # @param object_id [Integer] EA object ID
27
+ # @param name [String] Object name
28
+ # @return [void]
29
+ def register_object_name(object_id, name)
30
+ return if object_id.nil?
31
+
32
+ @object_id_to_name[object_id] = name
33
+ end
34
+
35
+ # Resolve EA GUID to UML element
36
+ # @param ea_guid [String] EA GUID
37
+ # @return [Object, nil] UML element or nil if not found
38
+ def resolve(ea_guid)
39
+ return nil if ea_guid.nil?
40
+
41
+ @guid_to_element[normalize_guid(ea_guid)]
42
+ end
43
+
44
+ # Get object name by object ID
45
+ # @param object_id [Integer] EA object ID
46
+ # @return [String, nil] Object name or nil if not found
47
+ def resolve_object_name(object_id)
48
+ return nil if object_id.nil?
49
+
50
+ @object_id_to_name[object_id]
51
+ end
52
+
53
+ # Get UML xmi_id by EA GUID
54
+ # @param ea_guid [String] EA GUID
55
+ # @return [String, nil] xmi_id or nil if not found
56
+ def resolve_xmi_id(ea_guid)
57
+ element = resolve(ea_guid)
58
+ element&.xmi_id
59
+ end
60
+
61
+ # Check if GUID is registered
62
+ # @param ea_guid [String] EA GUID
63
+ # @return [Boolean] True if registered
64
+ def registered?(ea_guid)
65
+ return false if ea_guid.nil?
66
+
67
+ @guid_to_element.key?(normalize_guid(ea_guid))
68
+ end
69
+
70
+ # Clear all mappings
71
+ # @return [void]
72
+ def clear
73
+ @guid_to_element.clear
74
+ @object_id_to_name.clear
75
+ end
76
+
77
+ # Get statistics
78
+ # @return [Hash] Statistics about registered elements
79
+ def stats
80
+ {
81
+ total_elements: @guid_to_element.size,
82
+ total_objects: @object_id_to_name.size,
83
+ }
84
+ end
85
+
86
+ private
87
+
88
+ # Normalize GUID format (remove braces, upcase)
89
+ # @param guid [String] GUID string
90
+ # @return [String] Normalized GUID
91
+ def normalize_guid(guid)
92
+ return guid if guid.nil?
93
+
94
+ guid.to_s.gsub(/[{}]/, "").upcase
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_transformer"
4
+ require "lutaml/uml"
5
+
6
+ module Lutaml
7
+ module Qea
8
+ module Factory
9
+ # Transforms EA TaggedValue to UML TaggedValue
10
+ #
11
+ # This transformer converts Enterprise Architect tagged value
12
+ # definitions (custom metadata) to standard UML TaggedValue objects.
13
+ #
14
+ # @example Transform a tagged value
15
+ # ea_tag = Models::EaTaggedValue.new(
16
+ # property_id: "{GUID}",
17
+ # element_id: "{ELEMENT-GUID}",
18
+ # base_class: "ASSOCIATION_SOURCE",
19
+ # tag_value: "sequenceNumber|15$ea_notes=Unique integer..."
20
+ # )
21
+ # transformer = TaggedValueTransformer.new(database)
22
+ # uml_tag = transformer.transform(ea_tag)
23
+ class TaggedValueTransformer < BaseTransformer
24
+ # Transform EA tagged value to UML TaggedValue
25
+ #
26
+ # @param ea_tag [Models::EaTaggedValue] EA tagged value model
27
+ # @return [Lutaml::Uml::TaggedValue, nil] UML tagged value or nil
28
+ def transform(ea_tag)
29
+ return nil unless ea_tag
30
+ return nil unless ea_tag.tag_name
31
+
32
+ Lutaml::Uml::TaggedValue.new.tap do |tag|
33
+ tag.name = ea_tag.tag_name
34
+ tag.value = ea_tag.parsed_value || ""
35
+ tag.notes = ea_tag.parsed_notes
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "class_transformer"
4
+ require_relative "attribute_transformer"
5
+ require_relative "operation_transformer"
6
+ require_relative "association_transformer"
7
+ require_relative "generalization_transformer"
8
+ require_relative "package_transformer"
9
+ require_relative "diagram_transformer"
10
+
11
+ module Lutaml
12
+ module Qea
13
+ module Factory
14
+ # Registry for EA to UML transformers
15
+ # Implements the Registry pattern for transformer lookup
16
+ class TransformerRegistry
17
+ class << self
18
+ # Get or initialize the registry
19
+ # @return [Hash] Registry hash
20
+ def registry
21
+ @registry ||= {}
22
+ end
23
+
24
+ # Register a transformer for an EA type
25
+ # @param ea_type [Symbol, String] EA model type
26
+ # @param transformer_class [Class] Transformer class
27
+ def register(ea_type, transformer_class)
28
+ registry[ea_type.to_sym] = transformer_class
29
+ end
30
+
31
+ # Get transformer for an EA type
32
+ # @param ea_type [Symbol, String] EA model type
33
+ # @return [Class, nil] Transformer class or nil if not found
34
+ def transformer_for(ea_type)
35
+ registry[ea_type.to_sym]
36
+ end
37
+
38
+ # Get all registered transformers
39
+ # @return [Hash] All registered transformers
40
+ def all_transformers
41
+ registry.dup
42
+ end
43
+
44
+ # Check if a transformer is registered for a type
45
+ # @param ea_type [Symbol, String] EA model type
46
+ # @return [Boolean] True if registered
47
+ def registered?(ea_type)
48
+ registry.key?(ea_type.to_sym)
49
+ end
50
+
51
+ # Clear all registrations (mainly for testing)
52
+ def clear
53
+ @registry = {}
54
+ end
55
+
56
+ # Reset to default registrations
57
+ def reset_defaults
58
+ clear
59
+ register_defaults
60
+ end
61
+
62
+ # Register default transformers
63
+ def register_defaults
64
+ # Object types
65
+ register(:class, ClassTransformer)
66
+ register(:interface, ClassTransformer)
67
+ register(:package, PackageTransformer)
68
+
69
+ # Connector types
70
+ register(:association, AssociationTransformer)
71
+ register(:generalization, GeneralizationTransformer)
72
+
73
+ # Other types
74
+ register(:attribute, AttributeTransformer)
75
+ register(:operation, OperationTransformer)
76
+ register(:diagram, DiagramTransformer)
77
+ end
78
+ end
79
+
80
+ # Initialize registry with default transformers
81
+ register_defaults
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sqlite3"
4
+
5
+ module Lutaml
6
+ module Qea
7
+ # Utility for detecting and validating QEA files
8
+ class FileDetector
9
+ # SQLite magic bytes
10
+ SQLITE_MAGIC = "SQLite format 3\x00"
11
+
12
+ # Required EA tables for valid QEA file
13
+ REQUIRED_EA_TABLES = %w[
14
+ t_object
15
+ t_attribute
16
+ t_connector
17
+ t_package
18
+ ].freeze
19
+
20
+ class << self
21
+ # Check if file is a QEA file
22
+ #
23
+ # @param path [String] File path
24
+ # @return [Boolean] True if file appears to be QEA
25
+ def qea_file?(path)
26
+ return false unless File.exist?(path)
27
+ return false unless File.file?(path)
28
+ return false unless path.end_with?(".qea")
29
+
30
+ # Quick check: is it SQLite?
31
+ sqlite_file?(path)
32
+ end
33
+
34
+ # Validate QEA file structure
35
+ #
36
+ # @param path [String] File path
37
+ # @return [Hash] Validation result with :valid, :errors, :warnings
38
+ #
39
+ # @example
40
+ # result = FileDetector.validate_qea("model.qea")
41
+ # if result[:valid]
42
+ # puts "Valid QEA file"
43
+ # else
44
+ # puts "Errors: #{result[:errors]}"
45
+ # end
46
+ def validate_qea(path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
47
+ errors = []
48
+ warnings = []
49
+
50
+ # Check file exists
51
+ unless File.exist?(path)
52
+ return {
53
+ valid: false,
54
+ errors: ["File not found: #{path}"],
55
+ warnings: [],
56
+ }
57
+ end
58
+
59
+ # Check file extension
60
+ unless path.end_with?(".qea")
61
+ warnings << "File does not have .qea extension"
62
+ end
63
+
64
+ # Check SQLite format
65
+ unless sqlite_file?(path)
66
+ errors << "File is not a valid SQLite database"
67
+ return { valid: false, errors: errors, warnings: warnings }
68
+ end
69
+
70
+ # Check for EA tables
71
+ begin
72
+ db = SQLite3::Database.new(path, readonly: true)
73
+ tables = get_table_names(db)
74
+
75
+ REQUIRED_EA_TABLES.each do |required_table|
76
+ unless tables.include?(required_table)
77
+ errors << "Missing required EA table: #{required_table}"
78
+ end
79
+ end
80
+
81
+ # Check for data
82
+ if tables.include?("t_object")
83
+ count = db.execute("SELECT COUNT(*) FROM t_object").first.first
84
+ if count.zero?
85
+ warnings << "No objects found in t_object table"
86
+ end
87
+ end
88
+ rescue SQLite3::Exception => e
89
+ errors << "Failed to open database: #{e.message}"
90
+ ensure
91
+ db&.close
92
+ end
93
+
94
+ {
95
+ valid: errors.empty?,
96
+ errors: errors,
97
+ warnings: warnings,
98
+ }
99
+ end
100
+
101
+ # Get file information
102
+ #
103
+ # @param path [String] File path
104
+ # @return [Hash] File information
105
+ #
106
+ # @example
107
+ # info = FileDetector.file_info("model.qea")
108
+ # puts "Size: #{info[:size_mb]} MB"
109
+ # puts "Tables: #{info[:table_count]}"
110
+ def file_info(path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
111
+ return { error: "File not found" } unless File.exist?(path)
112
+
113
+ info = {
114
+ path: path,
115
+ size_bytes: File.size(path),
116
+ size_mb: (File.size(path) / 1024.0 / 1024.0).round(2),
117
+ modified: File.mtime(path),
118
+ is_qea: qea_file?(path),
119
+ }
120
+
121
+ if sqlite_file?(path)
122
+ begin
123
+ db = SQLite3::Database.new(path, readonly: true)
124
+ tables = get_table_names(db)
125
+ info[:is_sqlite] = true
126
+ info[:table_count] = tables.size
127
+ info[:has_ea_tables] = REQUIRED_EA_TABLES.all? do |t|
128
+ tables.include?(t)
129
+ end
130
+
131
+ # Get record counts for key tables
132
+ if tables.include?("t_object")
133
+ info[:object_count] =
134
+ db.execute("SELECT COUNT(*) FROM t_object").first.first
135
+ end
136
+ if tables.include?("t_package")
137
+ info[:package_count] =
138
+ db.execute("SELECT COUNT(*) FROM t_package").first.first
139
+ end
140
+ rescue SQLite3::Exception => e
141
+ info[:error] = e.message
142
+ ensure
143
+ db&.close
144
+ end
145
+ else
146
+ info[:is_sqlite] = false
147
+ end
148
+
149
+ info
150
+ end
151
+
152
+ private
153
+
154
+ # Check if file is SQLite database
155
+ #
156
+ # @param path [String] File path
157
+ # @return [Boolean] True if SQLite database
158
+ def sqlite_file?(path)
159
+ File.open(path, "rb") do |f|
160
+ magic = f.read(16)
161
+ magic == SQLITE_MAGIC
162
+ end
163
+ rescue StandardError
164
+ false
165
+ end
166
+
167
+ # Get table names from database
168
+ #
169
+ # @param db [SQLite3::Database] Database connection
170
+ # @return [Array<String>] Table names
171
+ def get_table_names(db)
172
+ db.execute("SELECT name FROM sqlite_master WHERE type='table'")
173
+ .flatten
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end