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.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +63 -0
- data/.github/workflows/links.yml +99 -0
- data/.github/workflows/rake.yml +13 -2
- data/.github/workflows/release.yml +12 -6
- data/.gitignore +3 -0
- data/.rubocop.yml +11 -3
- data/.rubocop_todo.yml +336 -0
- data/Gemfile +18 -7
- data/README.adoc +1854 -21
- data/Rakefile +7 -1
- data/bin/plantuml2lutaml +3 -3
- data/bin/yaml2lutaml +2 -2
- data/config/diagram_styles.yml +200 -0
- data/config/model_transformations.yml +266 -0
- data/config/package_metadata.example.yml +58 -0
- data/config/qea_schema.yml +1024 -0
- data/config/static_site.yml +166 -0
- data/docs/.github/workflows/docs.yml +66 -0
- data/docs/.github/workflows/links.yml +78 -0
- data/docs/CONTINUATION_PLAN.md +168 -0
- data/docs/Gemfile +13 -0
- data/docs/MIGRATION_GUIDE.md +202 -0
- data/docs/README.md +252 -0
- data/docs/REFACTOR_PLAN.md +214 -0
- data/docs/_config.yml +144 -0
- data/docs/_guides/diagram-generation.adoc +316 -0
- data/docs/_guides/index.adoc +135 -0
- data/docs/{lutaml-express.adoc → _guides/parsing/express-parsing.adoc} +7 -0
- data/docs/_guides/parsing/index.adoc +77 -0
- data/docs/{lutaml-xmi.adoc → _guides/parsing/xmi-parsing.adoc} +7 -0
- data/docs/_guides/sysml-modeling.adoc +37 -0
- data/docs/{lutaml-uml.adoc → _guides/uml-modeling.adoc} +8 -2
- data/docs/_pages/concepts/diagram-generation.adoc +337 -0
- data/docs/_pages/concepts/lur-format.adoc +711 -0
- data/docs/_pages/concepts/qea-parsing.adoc +418 -0
- data/docs/_pages/core/architecture.adoc +329 -0
- data/docs/_pages/core/installation.adoc +321 -0
- data/docs/_pages/core/overview.adoc +197 -0
- data/docs/_pages/index.adoc +48 -0
- data/docs/_pages/uml-syntax.adoc +995 -0
- data/docs/_references/configuration/diagram-styles.adoc +716 -0
- data/docs/_references/configuration/index.adoc +52 -0
- data/docs/_references/configuration/package-metadata.adoc +416 -0
- data/docs/_references/formats/index.adoc +42 -0
- data/docs/{lutaml_syntax.adoc → _references/formats/lutaml-syntax.adoc} +7 -0
- data/docs/_references/formats/qea-structure.adoc +1364 -0
- data/docs/_references/index.adoc +197 -0
- data/docs/_tutorials/index.adoc +109 -0
- data/docs/index.adoc +64 -0
- data/docs/lychee.toml +83 -0
- data/examples/UML_EA.DTD +6856 -0
- data/examples/lur/20251010_current_plateau_v5.1.lur +0 -0
- data/examples/lur/basic.lur +0 -0
- data/examples/lur/test-output.lur +0 -0
- data/examples/lur/test.lur +0 -0
- data/examples/lur_basic_usage.rb +220 -0
- data/examples/lur_cli_workflow.rb +262 -0
- data/examples/lur_statistics.rb +325 -0
- data/examples/qea/20251010_current_plateau_v5.1.qea +0 -0
- data/examples/qea/ArcGISWorkspace_template.qea +0 -0
- data/examples/qea/README_qea_parser.adoc +230 -0
- data/examples/qea/UmlModel_template.qea +0 -0
- data/examples/qea/basic.qea +0 -0
- data/examples/qea/simple.qea +0 -0
- data/examples/qea/simple_example.qea +0 -0
- data/examples/qea/test.qea +0 -0
- data/examples/xmi/20251010_current_plateau_v5.1.xmi +118121 -0
- data/examples/xmi/ArcGISWorkspace_template.xmi +1467 -0
- data/examples/xmi/Images/EAID_0016F797_D055_4717_AF1A_606413D0A166.svg +158 -0
- data/examples/xmi/Images/EAID_00C5C772_5A03_434f_BF30_AC37542A1AAC.svg +659 -0
- data/examples/xmi/Images/EAID_0114FD24_9E58_4664_98CD_71305B59AD11.svg +411 -0
- data/examples/xmi/Images/EAID_01661E1B_31B6_4167_BCCF_A00678FB4EA2.svg +102 -0
- data/examples/xmi/Images/EAID_039FE004_5408_4fc0_89AA_EB319E4F61C7.svg +169 -0
- data/examples/xmi/Images/EAID_04EE9625_17A0_4721_BC71_21756DB21D06.svg +403 -0
- data/examples/xmi/Images/EAID_05FF9417_1619_4170_B0C9_55AA6B988EF1.svg +175 -0
- data/examples/xmi/Images/EAID_09853FB2_AF8A_432f_94C5_6C47461BD937.svg +360 -0
- data/examples/xmi/Images/EAID_09927B7F_A657_4819_99E5_AC9DC99227D9.svg +195 -0
- data/examples/xmi/Images/EAID_09AF6B8A_557C_43bc_BBB0_47C1E9401EF3.svg +218 -0
- data/examples/xmi/Images/EAID_0BE81AC5_031B_4973_A9A0_223CCD92BAA1.svg +471 -0
- data/examples/xmi/Images/EAID_0EDEA6EF_4DC8_4979_BB80_28B1B9EBD1D4.svg +56 -0
- data/examples/xmi/Images/EAID_0F413534_6AD2_48bc_B4AF_8699D530D91D.svg +262 -0
- data/examples/xmi/Images/EAID_1321F39B_AD67_47b5_B5C3_3A42BBFCBDF9.svg +286 -0
- data/examples/xmi/Images/EAID_13E09C71_99E7_40b4_B72D_48AF6379BC2E.svg +164 -0
- data/examples/xmi/Images/EAID_144955D8_CB4E_4b59_BB0C_E549F7F84943.svg +66 -0
- data/examples/xmi/Images/EAID_14E9F5FD_F6CD_4f48_B1CD_F5A40C6D8E83.svg +95 -0
- data/examples/xmi/Images/EAID_157826AA_96A7_4278_89A6_94BD0F31409A.svg +63 -0
- data/examples/xmi/Images/EAID_159E9DA0_7A54_4817_B72A_401C750F675D.svg +306 -0
- data/examples/xmi/Images/EAID_17BC8309_8051_492b_BE87_61CCFE83DB16.svg +45 -0
- data/examples/xmi/Images/EAID_1A10EB6D_E2E5_42a6_A31E_B293D93FD07E.svg +193 -0
- data/examples/xmi/Images/EAID_1A290AFD_CE96_46a2_8351_A986D77CC727.svg +444 -0
- data/examples/xmi/Images/EAID_1B2D9309_C66B_492a_995C_95B2B02E0D7C.svg +168 -0
- data/examples/xmi/Images/EAID_1DE6B973_CE8A_416f_909B_54CEA1E5944E.svg +10 -0
- data/examples/xmi/Images/EAID_204F4ACC_2230_4c8d_9861_EF5A6844B712.svg +60 -0
- data/examples/xmi/Images/EAID_227300E2_4F4B_4955_83B9_FA626CE8680B.svg +188 -0
- data/examples/xmi/Images/EAID_22C24D4C_4894_480a_B113_0CB034CB59E9.svg +426 -0
- data/examples/xmi/Images/EAID_234BC4F5_8100_4969_BDCB_A24E0E641F23.svg +169 -0
- data/examples/xmi/Images/EAID_24446BFC_9FEB_4935_8970_65A4C562A93F.svg +277 -0
- data/examples/xmi/Images/EAID_24E8A45C_C99F_49b7_860A_9CF65FF76C76.svg +575 -0
- data/examples/xmi/Images/EAID_272F3181_4300_48b7_98A0_A8CFD12B1A72.svg +255 -0
- data/examples/xmi/Images/EAID_292E0D94_392C_4da6_A0B5_841501FAE50A.svg +183 -0
- data/examples/xmi/Images/EAID_29DD0967_ADAB_4abb_99C5_544821F5E7DA.svg +10 -0
- data/examples/xmi/Images/EAID_2A339928_E5EF_4ed2_9E5D_CC2CA5CF248B.svg +310 -0
- data/examples/xmi/Images/EAID_2A5E0832_06BE_4381_85D4_9B00E4F95575.svg +155 -0
- data/examples/xmi/Images/EAID_2AAB709F_EFCE_496f_8AFE_92809D66A0A9.svg +81 -0
- data/examples/xmi/Images/EAID_2C8DD882_8DEA_4065_89F8_DDA796AA0C85.svg +520 -0
- data/examples/xmi/Images/EAID_2E98EA19_37D8_4b70_BDCE_CFEE4FA800B0.svg +173 -0
- data/examples/xmi/Images/EAID_30D62231_110F_44e8_9C06_6FCDCBA53A09.svg +722 -0
- data/examples/xmi/Images/EAID_3206D3FD_1FC4_41c7_8D00_36DB908E9319.svg +181 -0
- data/examples/xmi/Images/EAID_3452CC53_9ACB_44eb_9C9D_B90CF862F284.svg +92 -0
- data/examples/xmi/Images/EAID_348EE46E_ABD9_40b0_82A1_0285E75BDC52.svg +187 -0
- data/examples/xmi/Images/EAID_34FF671B_CFDC_47ad_91DF_ECA6D8358180.svg +217 -0
- data/examples/xmi/Images/EAID_359DD694_0100_4bdf_AD5F_712D97E9C69B.svg +157 -0
- data/examples/xmi/Images/EAID_35DE714C_49A8_490e_913A_56F39EF317F9.svg +180 -0
- data/examples/xmi/Images/EAID_360C79F1_8EDF_41db_A069_DECDC55625BC.svg +31 -0
- data/examples/xmi/Images/EAID_36913C58_FF35_4ba2_A04B_9A4824E24609.svg +166 -0
- data/examples/xmi/Images/EAID_372F7F7B_57ED_469a_A640_70DB578B3C56.svg +361 -0
- data/examples/xmi/Images/EAID_37AC19B9_8433_4fee_A326_763170D54D06.svg +32 -0
- data/examples/xmi/Images/EAID_38170608_32B5_4a6f_A68D_A0D7C0C9D019.svg +234 -0
- data/examples/xmi/Images/EAID_3A77A5D0_4E1B_4116_8AAD_407FC422B47F.svg +183 -0
- data/examples/xmi/Images/EAID_3B8BD087_1683_46b1_8D0D_6F839C46C578.svg +42 -0
- data/examples/xmi/Images/EAID_3DC20801_AE8B_4e76_B08C_F574E8A90E13.svg +192 -0
- data/examples/xmi/Images/EAID_3DE28C70_C6D4_406c_B49F_EEF52148C8C1.svg +124 -0
- data/examples/xmi/Images/EAID_458E093C_BA2B_4292_BEC4_37511C163DDC.svg +140 -0
- data/examples/xmi/Images/EAID_45F9B1F7_E568_47c9_B229_953BC2E707E4.svg +266 -0
- data/examples/xmi/Images/EAID_46B3041A_8C23_46e6_8E14_ADE7012274C5.svg +80 -0
- data/examples/xmi/Images/EAID_47E4600F_CEC9_4245_9BF5_EE38007A9DDB.svg +584 -0
- data/examples/xmi/Images/EAID_4881CEEE_792C_4cb0_BEA7_54333B643D0A.svg +155 -0
- data/examples/xmi/Images/EAID_48D364F0_DCA4_41e8_B4D4_509B3023B969.svg +17 -0
- data/examples/xmi/Images/EAID_4DBDAB9E_4C1C_4cb1_A767_06BD743A50A7.svg +78 -0
- data/examples/xmi/Images/EAID_4EB75007_B31D_4f2c_8855_7E9D3A3B17F4.svg +454 -0
- data/examples/xmi/Images/EAID_4F421236_FCF3_4aae_B22A_C7E6A5EFBAC7.svg +81 -0
- data/examples/xmi/Images/EAID_4FC1D352_2102_4b73_BCB0_1410B29C6BD7.svg +379 -0
- data/examples/xmi/Images/EAID_4FE346EA_01E1_4b30_8BE6_BB32EA191E47.svg +126 -0
- data/examples/xmi/Images/EAID_5038EEE3_7DD0_4cca_9829_364E044D37E8.svg +199 -0
- data/examples/xmi/Images/EAID_508A37DC_9378_4f5a_BD96_48F4D24E03A5.svg +162 -0
- data/examples/xmi/Images/EAID_516DA1A2_F0EC_415c_9664_E4CA54E7F05C.svg +136 -0
- data/examples/xmi/Images/EAID_52A1DBD3_D3DA_4b6d_8F96_FC6F39F64242.svg +161 -0
- data/examples/xmi/Images/EAID_575E87BA_32E9_4a84_AA4E_0EFDFC5D4C07.svg +71 -0
- data/examples/xmi/Images/EAID_57E0F1A0_6C72_47ef_B922_B806F9A875E8.svg +209 -0
- data/examples/xmi/Images/EAID_5957C373_3FC1_482f_8F35_D809153A17F5.svg +123 -0
- data/examples/xmi/Images/EAID_59A66AE2_412C_48a6_BFC7_EA56CF11D269.svg +218 -0
- data/examples/xmi/Images/EAID_5A43833E_680B_4a90_8931_0C902304E029.svg +236 -0
- data/examples/xmi/Images/EAID_5D6DB5A0_5047_4bac_9E60_69904A60B56D.svg +353 -0
- data/examples/xmi/Images/EAID_5DA1E7A7_8E59_4803_A831_E9F3EC27328F.svg +242 -0
- data/examples/xmi/Images/EAID_5E2C1E2A_82A8_47f4_B2ED_1398D72BFCFD.svg +246 -0
- data/examples/xmi/Images/EAID_6052620C_4BD5_49f6_A21C_AD7E6DCA2795.svg +290 -0
- data/examples/xmi/Images/EAID_6481E2CC_35A6_43b0_88D4_10A667A2BC2D.svg +60 -0
- data/examples/xmi/Images/EAID_660C7D03_A26C_4977_A7BA_9D0A773DA811.svg +318 -0
- data/examples/xmi/Images/EAID_671F3C3D_35B6_4514_B5B6_DD7E84925493.svg +24 -0
- data/examples/xmi/Images/EAID_676B9C9A_D85F_4d2f_A46B_73F02090DC87.svg +127 -0
- data/examples/xmi/Images/EAID_6797FEFA_5801_48e4_8B9C_3C824C0E165D.svg +412 -0
- data/examples/xmi/Images/EAID_6807F4EE_18EF_4e7e_ACCF_D5BD323AFDE9.svg +130 -0
- data/examples/xmi/Images/EAID_69E81E34_CF28_4c7f_A48F_5941BA85CEE3.svg +96 -0
- data/examples/xmi/Images/EAID_6A3C55E8_3C3C_4f3a_8AAC_0299C5B23070.svg +10 -0
- data/examples/xmi/Images/EAID_6BAC333E_E2C2_42c7_8DDF_6B4FA0FFC03B.svg +143 -0
- data/examples/xmi/Images/EAID_6D0349D5_3F1B_4b28_82D2_910743DEB5E5.svg +114 -0
- data/examples/xmi/Images/EAID_6E95B74E_8A09_4698_9E9E_23BCFD2CE194.svg +37 -0
- data/examples/xmi/Images/EAID_70C77F92_5614_4b22_8C8E_67859F59D8FD.svg +254 -0
- data/examples/xmi/Images/EAID_71F9216B_E7A7_4083_B08E_6C71B57F3A1F.svg +187 -0
- data/examples/xmi/Images/EAID_73025C5A_08FC_47ff_AB2F_C7F79CF54B41.svg +145 -0
- data/examples/xmi/Images/EAID_74C974B6_6D07_425d_B7AC_C8899E3B4967.svg +76 -0
- data/examples/xmi/Images/EAID_7504FCD2_524C_4e7d_BAE4_4E58A8A8A12C.svg +196 -0
- data/examples/xmi/Images/EAID_78030266_3603_4747_9D75_03D16614BE7D.svg +35 -0
- data/examples/xmi/Images/EAID_785226C1_12B1_4104_A4C1_F19B70B9FB71.svg +348 -0
- data/examples/xmi/Images/EAID_7854470F_26B8_4d3c_AFDF_C05BCE6ED0CD.svg +72 -0
- data/examples/xmi/Images/EAID_794F4A8F_18CA_4e9f_8477_A6F0E5ED22D4.svg +187 -0
- data/examples/xmi/Images/EAID_7A24839E_C8AE_424d_B7D2_6DA16DC813E7.svg +114 -0
- data/examples/xmi/Images/EAID_7A3649FD_E960_4ae6_B9B1_A9001C066AE7.svg +181 -0
- data/examples/xmi/Images/EAID_7B2C6765_AB68_439a_87F3_DAC323CB2AF5.svg +196 -0
- data/examples/xmi/Images/EAID_7C44AC09_27C1_47b3_9A85_88EC71C081FF.svg +55 -0
- data/examples/xmi/Images/EAID_7CE102CA_97C1_4cac_BD3B_0500D3712D2A.svg +195 -0
- data/examples/xmi/Images/EAID_7D960BD8_65D8_4934_9C11_4EF860DD8FBA.svg +90 -0
- data/examples/xmi/Images/EAID_80939C98_A456_48c3_BCEA_4B72851F2DF6.svg +174 -0
- data/examples/xmi/Images/EAID_812FE862_76ED_44f0_B678_7A4601B395CF.svg +142 -0
- data/examples/xmi/Images/EAID_81B76F5B_9D64_4bbf_8AC8_34234FB87533.svg +740 -0
- data/examples/xmi/Images/EAID_84352F1A_195B_411b_9552_5BFC40BF90B5.svg +105 -0
- data/examples/xmi/Images/EAID_846DD800_139C_4d47_A1DF_3FB1AC5D130F.svg +554 -0
- data/examples/xmi/Images/EAID_84A9C65B_FD6D_4bb5_818F_E8C35FF5BCD1.svg +228 -0
- data/examples/xmi/Images/EAID_853674F5_7DC9_4aae_809B_5728098B5D5B.svg +154 -0
- data/examples/xmi/Images/EAID_860CBBFB_2F27_408f_9144_751F9D1F487F.svg +273 -0
- data/examples/xmi/Images/EAID_87476527_7B9B_4b92_967E_3D38365470CA.svg +239 -0
- data/examples/xmi/Images/EAID_87DAE930_5069_4c58_AC65_4B0B2C0F32C8.svg +10 -0
- data/examples/xmi/Images/EAID_88AF6BD7_BC34_406f_BB59_47CFAB4A7D5D.svg +116 -0
- data/examples/xmi/Images/EAID_88D0CB44_20D0_44fc_A6E3_B663332EF401.svg +200 -0
- data/examples/xmi/Images/EAID_8BB1CA0C_C003_4678_973B_A1C3308E021D.svg +136 -0
- data/examples/xmi/Images/EAID_8DAB169F_D189_4320_A0F5_4443E3297F0E.svg +181 -0
- data/examples/xmi/Images/EAID_8FD488EF_BAAB_40ec_A7ED_F7CC831D546E.svg +324 -0
- data/examples/xmi/Images/EAID_90BCA409_BB45_42c5_AFA5_45FE3D995904.svg +342 -0
- data/examples/xmi/Images/EAID_926AFE38_01FA_469e_B6AA_ED5F4D62B66F.svg +105 -0
- data/examples/xmi/Images/EAID_92AB0FD0_B0FB_4ceb_8EAE_66B6600D31D7.svg +681 -0
- data/examples/xmi/Images/EAID_92C43670_3057_47f1_A576_C60843FF3D26.svg +136 -0
- data/examples/xmi/Images/EAID_93F63576_BE01_4cd8_8A91_C674FF77FC3D.svg +718 -0
- data/examples/xmi/Images/EAID_9400D9BC_05A5_41fc_83F7_02E5C67F9718.svg +487 -0
- data/examples/xmi/Images/EAID_95246DCF_1C09_4a16_9512_98000F56B3D8.svg +292 -0
- data/examples/xmi/Images/EAID_9994BF62_51E2_42cd_BB35_16C537B6718A.svg +715 -0
- data/examples/xmi/Images/EAID_9AAD6C21_B1E7_4472_B64A_FB5E3569D970.svg +116 -0
- data/examples/xmi/Images/EAID_9BD7189A_877B_4ca9_B42C_817DEF144FB2.svg +284 -0
- data/examples/xmi/Images/EAID_9DA6C553_94FC_4204_83AD_ECC4B45A53EF.svg +159 -0
- data/examples/xmi/Images/EAID_9EE6A41B_5FAA_4c89_B98F_732059778630.svg +10 -0
- data/examples/xmi/Images/EAID_9F1A4B54_46F6_435c_9529_E43E54CF6050.svg +172 -0
- data/examples/xmi/Images/EAID_9FE1EA7B_4CEF_4976_A281_93A94315BD84.svg +153 -0
- data/examples/xmi/Images/EAID_A0695647_6172_4262_8C30_67441399609C.svg +290 -0
- data/examples/xmi/Images/EAID_A081C63E_D6F2_41a7_A99C_307836754AFA.svg +149 -0
- data/examples/xmi/Images/EAID_A24E2778_5AD9_44f2_AB8F_5CD3913477D6.svg +194 -0
- data/examples/xmi/Images/EAID_A264F089_F9B3_406c_A3A8_FF34903797D3.svg +143 -0
- data/examples/xmi/Images/EAID_A282E5D1_2A13_4e7f_BC76_5D086DD4A577.svg +357 -0
- data/examples/xmi/Images/EAID_A3BCE1D6_9DB5_4272_A020_4C0E194B99CC.svg +171 -0
- data/examples/xmi/Images/EAID_A56E3818_D1B8_4b63_B69E_FBAC4A8AF482.svg +218 -0
- data/examples/xmi/Images/EAID_A57215D5_75C5_4532_BCF4_264A77CD62F1.svg +204 -0
- data/examples/xmi/Images/EAID_A59065AF_9669_486c_9582_9693177CFC7F.svg +263 -0
- data/examples/xmi/Images/EAID_A759374D_589A_488c_99EF_537ACB9B1FF9.svg +398 -0
- data/examples/xmi/Images/EAID_A7B25F46_F18A_4373_B16D_8C6AC0B868B0.svg +174 -0
- data/examples/xmi/Images/EAID_A9FE9E6F_A5F4_47e5_A6BA_26E22C7346B6.svg +310 -0
- data/examples/xmi/Images/EAID_AA62CDEB_55EC_498d_B326_4AA2C9AF6A05.svg +144 -0
- data/examples/xmi/Images/EAID_AAF52AF6_F7F9_4005_AE46_8920847BEA03.svg +144 -0
- data/examples/xmi/Images/EAID_AB281AC1_7CB8_404a_8124_34343DDD84E2.svg +198 -0
- data/examples/xmi/Images/EAID_AB7F1FDF_A66B_42a1_B8A3_7F594BAAD508.svg +143 -0
- data/examples/xmi/Images/EAID_AC2191E3_76E3_40b2_9E21_0E0B9B5277D2.svg +114 -0
- data/examples/xmi/Images/EAID_AD451676_A7C8_4c6a_A925_A9B9CA344142.svg +339 -0
- data/examples/xmi/Images/EAID_ADBA40A1_9375_4c1b_9938_0990612EB615.svg +429 -0
- data/examples/xmi/Images/EAID_ADC8773C_1B27_48ac_BAC1_14C1C919FAF6.svg +245 -0
- data/examples/xmi/Images/EAID_AE0718DF_AF69_4ea1_A099_E20028FE40A1.svg +173 -0
- data/examples/xmi/Images/EAID_B0DDB85D_A00C_4a7f_8C06_CCA15E5E4FE5.svg +31 -0
- data/examples/xmi/Images/EAID_B27ED282_D5E5_4f33_8AC1_62802F9E0B35.svg +256 -0
- data/examples/xmi/Images/EAID_B3AFECCB_17DD_44d6_8A44_2C38D9A64C0B.svg +95 -0
- data/examples/xmi/Images/EAID_B3B6C5B1_278E_4714_8244_B6C28B66AB50.svg +176 -0
- data/examples/xmi/Images/EAID_B53E76CD_A0F2_4e2f_B3AB_796D85964EF2.svg +179 -0
- data/examples/xmi/Images/EAID_B55D6E67_0BDD_4163_B359_11A6FBA89C74.svg +207 -0
- data/examples/xmi/Images/EAID_B58D1A53_E860_41a3_8352_11C274093E83.svg +189 -0
- data/examples/xmi/Images/EAID_B62C02B3_69DB_49e9_8089_4EE398BDE666.svg +165 -0
- data/examples/xmi/Images/EAID_BC008774_B539_4150_8174_B675989053D0.svg +22 -0
- data/examples/xmi/Images/EAID_BC1F7E00_082D_4a26_922B_3967A8D66859.svg +266 -0
- data/examples/xmi/Images/EAID_BDA613D8_402A_475a_AA15_683D88FD3D23.svg +183 -0
- data/examples/xmi/Images/EAID_C028B286_4C85_47d8_B6D5_80B28F556E82.svg +303 -0
- data/examples/xmi/Images/EAID_C173A6F4_1D1B_400e_AD8C_64FFF7CD5BE5.svg +178 -0
- data/examples/xmi/Images/EAID_C1834072_CADC_4ce4_B0FC_8284AE5CF4A4.svg +158 -0
- data/examples/xmi/Images/EAID_C1EC985B_5CBD_4e91_8661_EB4EF23781D9.svg +286 -0
- data/examples/xmi/Images/EAID_C31C1314_B679_4413_B8FE_A2CD584FC128.svg +305 -0
- data/examples/xmi/Images/EAID_C37CFBD6_69BA_42fb_9AC7_2D329D931BCF.svg +171 -0
- data/examples/xmi/Images/EAID_C857C934_306F_463a_87D5_257CB225ECFE.svg +174 -0
- data/examples/xmi/Images/EAID_C96797DE_2238_42d3_896A_9F92500270ED.svg +180 -0
- data/examples/xmi/Images/EAID_C96CBC24_B20E_459a_8F9D_75B61CDCB89F.svg +656 -0
- data/examples/xmi/Images/EAID_CACB523D_56A5_4f05_B3C2_51BB18F380FD.svg +158 -0
- data/examples/xmi/Images/EAID_CB34B578_101B_48b4_9271_214FFEA6A83A.svg +409 -0
- data/examples/xmi/Images/EAID_CBBD6CF4_0A1E_4406_9930_89DE43527910.svg +361 -0
- data/examples/xmi/Images/EAID_CC06A828_3750_472f_8DB2_C2E0863FCE17.svg +96 -0
- data/examples/xmi/Images/EAID_CD5CF053_1772_4a0f_962D_B17054D8EEAA.svg +173 -0
- data/examples/xmi/Images/EAID_CE440B5A_9534_4c75_9BA5_50862BB396C2.svg +97 -0
- data/examples/xmi/Images/EAID_CE4734FC_7986_4b3a_807F_A5B2C7EDE9E4.svg +193 -0
- data/examples/xmi/Images/EAID_D14AA320_9D41_4366_8739_9C2C21F96AE1.svg +32 -0
- data/examples/xmi/Images/EAID_D2FA55D3_C733_4a4d_92D0_0BC7AC0BB5BC.svg +108 -0
- data/examples/xmi/Images/EAID_D351FC34_FB03_488d_ADA4_BDB93DA9CB02.svg +49 -0
- data/examples/xmi/Images/EAID_D368FDF3_BDC5_4718_A701_351C8587A376.svg +592 -0
- data/examples/xmi/Images/EAID_D4DA8C48_3998_450d_87C4_9D65C9FECDB4.svg +42 -0
- data/examples/xmi/Images/EAID_D5464ECF_290E_4b2b_A6C4_25BE80F886CB.svg +76 -0
- data/examples/xmi/Images/EAID_D55235B0_61E9_461a_8379_2B8BF2403BE2.svg +147 -0
- data/examples/xmi/Images/EAID_D555ED73_F010_45d7_8A53_45A33C64C249.svg +318 -0
- data/examples/xmi/Images/EAID_D7AAC526_267E_45a0_A853_3207F02363F8.svg +45 -0
- data/examples/xmi/Images/EAID_D998B20D_A875_4ef8_A9CE_996BE56602BD.svg +158 -0
- data/examples/xmi/Images/EAID_DBFA8B39_F5B7_4c0e_9552_19AEAE5BA64E.svg +200 -0
- data/examples/xmi/Images/EAID_DE47A47D_E7BE_4e6f_BA81_F789EE8CFE72.svg +61 -0
- data/examples/xmi/Images/EAID_DFBB1072_8EC5_4384_8241_7EDF4B6B888B.svg +78 -0
- data/examples/xmi/Images/EAID_E325B9D8_E955_4aed_8125_63167BD40320.svg +67 -0
- data/examples/xmi/Images/EAID_E32D9D02_CAE9_4a47_92A8_3290EDCD6E6D.svg +79 -0
- data/examples/xmi/Images/EAID_E3B28611_7857_458a_B0BC_736E777B88EC.svg +194 -0
- data/examples/xmi/Images/EAID_E43C37EC_1176_4d2e_8B98_B6F3DFF6A092.svg +96 -0
- data/examples/xmi/Images/EAID_E591C1CF_7F35_4160_8A72_DFA097AD5811.svg +271 -0
- data/examples/xmi/Images/EAID_E77C66A2_2E94_4196_BFC6_662FE5AEEB6F.svg +332 -0
- data/examples/xmi/Images/EAID_E7AABA98_2450_4986_9736_DCCAF0108C50.svg +639 -0
- data/examples/xmi/Images/EAID_E7D9A2C4_72D6_40b9_8EB8_6B35476246B3.svg +134 -0
- data/examples/xmi/Images/EAID_E9CDAD85_ECF1_43de_819F_30A0D01785E6.svg +193 -0
- data/examples/xmi/Images/EAID_EC8AF507_F441_4e8a_B8A7_C1690F3C7D0B.svg +58 -0
- data/examples/xmi/Images/EAID_ED501058_D540_47ac_8EBC_5921E8C0BF57.svg +384 -0
- data/examples/xmi/Images/EAID_EFBF5F0F_DF74_4944_8791_114F5637C335.svg +590 -0
- data/examples/xmi/Images/EAID_EFFFA027_2A1F_425c_8437_BF89AADC8893.svg +365 -0
- data/examples/xmi/Images/EAID_F07E7718_B2C2_4a65_B5DD_477CB73E971E.svg +165 -0
- data/examples/xmi/Images/EAID_F0F20BDF_C729_47f7_B6FC_25ED2C4609CA.svg +61 -0
- data/examples/xmi/Images/EAID_F32E5AFE_8605_4c77_AE69_D0D0A6E380AC.svg +76 -0
- data/examples/xmi/Images/EAID_F3F00F45_CD37_46fd_B521_D1040EB2FB16.svg +123 -0
- data/examples/xmi/Images/EAID_F46E8F19_D8F1_4a3d_B87B_B0BAB4F50F50.svg +202 -0
- data/examples/xmi/Images/EAID_F48E5F6E_2411_4635_9315_3EAA4CFA29F7.svg +351 -0
- data/examples/xmi/Images/EAID_F4C23F9E_DD74_4fed_B75D_AD3C6448BA24.svg +189 -0
- data/examples/xmi/Images/EAID_F853B3C4_B145_4ef0_B261_C3CC0475B6D2.svg +215 -0
- data/examples/xmi/Images/EAID_F8BE68CA_1F8F_47e5_9454_01A2EB7D388A.svg +124 -0
- data/examples/xmi/Images/EAID_F92A6A28_612E_468e_9E39_D7AE7D24E24D.svg +208 -0
- data/examples/xmi/Images/EAID_F995FA49_B86E_4c94_BE5E_C928FB6B87D0.svg +302 -0
- data/examples/xmi/Images/EAID_FEAE013A_A4E4_4283_A491_1FEB8D0EBA28.svg +524 -0
- data/examples/xmi/Images/EAID_FEBE5726_3751_470b_9023_8C569202E97E.svg +730 -0
- data/examples/xmi/UML_EA.DTD +6856 -0
- data/examples/xmi/UmlModel_template.xmi +23 -0
- data/examples/xmi/basic.xmi +9086 -0
- data/examples/xmi/simple.xmi +655 -0
- data/examples/xmi/simple_example.xmi +23 -0
- data/examples/xmi/test.xmi +1703 -0
- data/exe/lutaml +2 -16
- data/exe/lutaml-wsd2uml +3 -3
- data/exe/lutaml-yaml2uml +2 -2
- data/lib/lutaml/cli/commands/base_command.rb +118 -0
- data/lib/lutaml/cli/element_identifier.rb +165 -0
- data/lib/lutaml/cli/enhanced_formatter.rb +502 -0
- data/lib/lutaml/cli/interactive_shell.rb +911 -0
- data/lib/lutaml/cli/lml_commands.rb +201 -0
- data/lib/lutaml/cli/output_formatter.rb +348 -0
- data/lib/lutaml/cli/resource_registry.rb +127 -0
- data/lib/lutaml/cli/tree_view_formatter.rb +308 -0
- data/lib/lutaml/cli/uml/build_command.rb +538 -0
- data/lib/lutaml/cli/uml/diagram_command.rb +421 -0
- data/lib/lutaml/cli/uml/export_command.rb +78 -0
- data/lib/lutaml/cli/uml/find_command.rb +122 -0
- data/lib/lutaml/cli/uml/info_command.rb +104 -0
- data/lib/lutaml/cli/uml/inspect_command.rb +88 -0
- data/lib/lutaml/cli/uml/ls_command.rb +105 -0
- data/lib/lutaml/cli/uml/repl_command.rb +50 -0
- data/lib/lutaml/cli/uml/search_command.rb +88 -0
- data/lib/lutaml/cli/uml/serve_command.rb +59 -0
- data/lib/lutaml/cli/uml/shared_helpers.rb +51 -0
- data/lib/lutaml/cli/uml/spa_command.rb +209 -0
- data/lib/lutaml/cli/uml/stats_command.rb +60 -0
- data/lib/lutaml/cli/uml/tree_command.rb +85 -0
- data/lib/lutaml/cli/uml/validate_command.rb +195 -0
- data/lib/lutaml/cli/uml/verify_command.rb +107 -0
- data/lib/lutaml/cli/uml_commands.rb +163 -0
- data/lib/lutaml/cli.rb +72 -0
- data/lib/lutaml/command_line.rb +8 -6
- data/lib/lutaml/converter/dsl_to_uml.rb +2 -0
- data/lib/lutaml/converter/xmi_to_uml.rb +40 -19
- data/lib/lutaml/ea/diagram/configuration.rb +379 -0
- data/lib/lutaml/ea/diagram/element_renderers/base_renderer.rb +81 -0
- data/lib/lutaml/ea/diagram/element_renderers/class_renderer.rb +330 -0
- data/lib/lutaml/ea/diagram/element_renderers/connector_renderer.rb +55 -0
- data/lib/lutaml/ea/diagram/element_renderers/package_renderer.rb +69 -0
- data/lib/lutaml/ea/diagram/extractor.rb +559 -0
- data/lib/lutaml/ea/diagram/layout_engine.rb +251 -0
- data/lib/lutaml/ea/diagram/path_builder.rb +258 -0
- data/lib/lutaml/ea/diagram/style_parser.rb +315 -0
- data/lib/lutaml/ea/diagram/style_resolver.rb +291 -0
- data/lib/lutaml/ea/diagram/svg_renderer.rb +285 -0
- data/lib/lutaml/ea/diagram/util.rb +69 -0
- data/lib/lutaml/ea/diagram.rb +77 -0
- data/lib/lutaml/express/parsers/exp.rb +1 -1
- data/lib/lutaml/express.rb +4 -2
- data/lib/lutaml/formatter/base.rb +6 -6
- data/lib/lutaml/formatter/graphviz.rb +10 -8
- data/lib/lutaml/formatter.rb +3 -0
- data/lib/lutaml/layout/engine.rb +9 -7
- data/lib/lutaml/layout/graph_viz_engine.rb +2 -1
- data/lib/lutaml/layout.rb +8 -0
- data/lib/lutaml/model_transformations/configuration.rb +333 -0
- data/lib/lutaml/model_transformations/format_registry.rb +394 -0
- data/lib/lutaml/model_transformations/parsers/base_parser.rb +389 -0
- data/lib/lutaml/model_transformations/parsers/qea_parser.rb +455 -0
- data/lib/lutaml/model_transformations/parsers/xmi_parser.rb +301 -0
- data/lib/lutaml/model_transformations/transformation_engine.rb +409 -0
- data/lib/lutaml/model_transformations.rb +143 -0
- data/lib/lutaml/parser.rb +15 -7
- data/lib/lutaml/qea/benchmark.rb +212 -0
- data/lib/lutaml/qea/database.rb +324 -0
- data/lib/lutaml/qea/factory/association_transformer.rb +115 -0
- data/lib/lutaml/qea/factory/attribute_tag_transformer.rb +60 -0
- data/lib/lutaml/qea/factory/attribute_transformer.rb +103 -0
- data/lib/lutaml/qea/factory/base_transformer.rb +132 -0
- data/lib/lutaml/qea/factory/class_transformer.rb +734 -0
- data/lib/lutaml/qea/factory/constraint_transformer.rb +78 -0
- data/lib/lutaml/qea/factory/data_type_transformer.rb +162 -0
- data/lib/lutaml/qea/factory/diagram_transformer.rb +182 -0
- data/lib/lutaml/qea/factory/document_builder.rb +275 -0
- data/lib/lutaml/qea/factory/ea_to_uml_factory.rb +260 -0
- data/lib/lutaml/qea/factory/enum_transformer.rb +87 -0
- data/lib/lutaml/qea/factory/generalization_transformer.rb +106 -0
- data/lib/lutaml/qea/factory/instance_transformer.rb +96 -0
- data/lib/lutaml/qea/factory/object_property_transformer.rb +61 -0
- data/lib/lutaml/qea/factory/operation_transformer.rb +75 -0
- data/lib/lutaml/qea/factory/package_transformer.rb +199 -0
- data/lib/lutaml/qea/factory/reference_resolver.rb +99 -0
- data/lib/lutaml/qea/factory/tagged_value_transformer.rb +41 -0
- data/lib/lutaml/qea/factory/transformer_registry.rb +85 -0
- data/lib/lutaml/qea/file_detector.rb +178 -0
- data/lib/lutaml/qea/infrastructure/database_connection.rb +100 -0
- data/lib/lutaml/qea/infrastructure/schema_reader.rb +136 -0
- data/lib/lutaml/qea/infrastructure/table_reader.rb +224 -0
- data/lib/lutaml/qea/models/base_model.rb +48 -0
- data/lib/lutaml/qea/models/ea_attribute.rb +135 -0
- data/lib/lutaml/qea/models/ea_attribute_tag.rb +109 -0
- data/lib/lutaml/qea/models/ea_complexity_type.rb +81 -0
- data/lib/lutaml/qea/models/ea_connector.rb +162 -0
- data/lib/lutaml/qea/models/ea_connector_type.rb +62 -0
- data/lib/lutaml/qea/models/ea_constraint_type.rb +65 -0
- data/lib/lutaml/qea/models/ea_datatype.rb +108 -0
- data/lib/lutaml/qea/models/ea_diagram.rb +117 -0
- data/lib/lutaml/qea/models/ea_diagram_link.rb +80 -0
- data/lib/lutaml/qea/models/ea_diagram_object.rb +86 -0
- data/lib/lutaml/qea/models/ea_diagram_type.rb +58 -0
- data/lib/lutaml/qea/models/ea_document.rb +68 -0
- data/lib/lutaml/qea/models/ea_object.rb +208 -0
- data/lib/lutaml/qea/models/ea_object_constraint.rb +62 -0
- data/lib/lutaml/qea/models/ea_object_property.rb +96 -0
- data/lib/lutaml/qea/models/ea_object_type.rb +75 -0
- data/lib/lutaml/qea/models/ea_operation.rb +153 -0
- data/lib/lutaml/qea/models/ea_operation_param.rb +73 -0
- data/lib/lutaml/qea/models/ea_package.rb +75 -0
- data/lib/lutaml/qea/models/ea_script.rb +69 -0
- data/lib/lutaml/qea/models/ea_status_type.rb +68 -0
- data/lib/lutaml/qea/models/ea_stereotype.rb +59 -0
- data/lib/lutaml/qea/models/ea_tagged_value.rb +105 -0
- data/lib/lutaml/qea/models/ea_xref.rb +174 -0
- data/lib/lutaml/qea/parser.rb +61 -0
- data/lib/lutaml/qea/repositories/base_repository.rb +215 -0
- data/lib/lutaml/qea/repositories/object_repository.rb +221 -0
- data/lib/lutaml/qea/services/configuration.rb +211 -0
- data/lib/lutaml/qea/services/database_loader.rb +215 -0
- data/lib/lutaml/qea/validation/association_validator.rb +75 -0
- data/lib/lutaml/qea/validation/attribute_validator.rb +103 -0
- data/lib/lutaml/qea/validation/base_validator.rb +305 -0
- data/lib/lutaml/qea/validation/class_validator.rb +123 -0
- data/lib/lutaml/qea/validation/database/circular_reference_validator.rb +111 -0
- data/lib/lutaml/qea/validation/database/orphan_validator.rb +155 -0
- data/lib/lutaml/qea/validation/database/referential_integrity_validator.rb +130 -0
- data/lib/lutaml/qea/validation/diagram_validator.rb +114 -0
- data/lib/lutaml/qea/validation/formatters/json_formatter.rb +137 -0
- data/lib/lutaml/qea/validation/formatters/text_formatter.rb +235 -0
- data/lib/lutaml/qea/validation/operation_validator.rb +81 -0
- data/lib/lutaml/qea/validation/package_validator.rb +113 -0
- data/lib/lutaml/qea/validation/validation_engine.rb +497 -0
- data/lib/lutaml/qea/validation/validation_message.rb +144 -0
- data/lib/lutaml/qea/validation/validation_result.rb +212 -0
- data/lib/lutaml/qea/validation/validator_registry.rb +134 -0
- data/lib/lutaml/qea/verification/comparison_result.rb +264 -0
- data/lib/lutaml/qea/verification/document_normalizer.rb +177 -0
- data/lib/lutaml/qea/verification/document_verifier.rb +320 -0
- data/lib/lutaml/qea/verification/element_comparator.rb +306 -0
- data/lib/lutaml/qea/verification/structure_matcher.rb +287 -0
- data/lib/lutaml/qea.rb +226 -0
- data/lib/lutaml/sysml/allocate.rb +2 -0
- data/lib/lutaml/sysml/allocated.rb +2 -0
- data/lib/lutaml/sysml/binding_connector.rb +2 -0
- data/lib/lutaml/sysml/block.rb +2 -0
- data/lib/lutaml/sysml/constraint_block.rb +2 -0
- data/lib/lutaml/sysml/copy.rb +2 -0
- data/lib/lutaml/sysml/derive_requirement.rb +2 -0
- data/lib/lutaml/sysml/nested_connector_end.rb +2 -0
- data/lib/lutaml/sysml/refine.rb +2 -0
- data/lib/lutaml/sysml/requirement.rb +2 -0
- data/lib/lutaml/sysml/requirement_related.rb +2 -0
- data/lib/lutaml/sysml/satisfy.rb +2 -0
- data/lib/lutaml/sysml/test_case.rb +2 -0
- data/lib/lutaml/sysml/trace.rb +2 -0
- data/lib/lutaml/sysml/verify.rb +2 -0
- data/lib/lutaml/sysml/xmi_file.rb +2 -0
- data/lib/lutaml/sysml.rb +3 -1
- data/lib/lutaml/uml/association.rb +4 -0
- data/lib/lutaml/uml/class.rb +11 -9
- data/lib/lutaml/uml/classifier.rb +3 -0
- data/lib/lutaml/uml/comment.rb +13 -0
- data/lib/lutaml/uml/data_type.rb +7 -6
- data/lib/lutaml/uml/diagram.rb +12 -0
- data/lib/lutaml/uml/diagram_link.rb +26 -0
- data/lib/lutaml/uml/diagram_object.rb +30 -0
- data/lib/lutaml/uml/document.rb +18 -0
- data/lib/lutaml/uml/enum.rb +4 -3
- data/lib/lutaml/uml/fontname.rb +13 -0
- data/lib/lutaml/uml/generalization.rb +2 -0
- data/lib/lutaml/uml/group.rb +2 -0
- data/lib/lutaml/uml/namespace.rb +2 -2
- data/lib/lutaml/uml/node/{field.rb → attribute.rb} +4 -4
- data/lib/lutaml/uml/node/base.rb +1 -1
- data/lib/lutaml/uml/node/class_node.rb +12 -12
- data/lib/lutaml/uml/node/class_relationship.rb +2 -2
- data/lib/lutaml/uml/node/document.rb +2 -2
- data/lib/lutaml/uml/node/method_argument.rb +3 -3
- data/lib/lutaml/uml/node/{method.rb → operation.rb} +4 -4
- data/lib/lutaml/uml/node/relationship.rb +3 -3
- data/lib/lutaml/uml/package.rb +7 -4
- data/lib/lutaml/uml/package_path.rb +235 -0
- data/lib/lutaml/uml/parsers/attribute.rb +2 -2
- data/lib/lutaml/uml/parsers/dsl.rb +3 -4
- data/lib/lutaml/uml/parsers/yaml.rb +1 -1
- data/lib/lutaml/uml/qualified_name.rb +178 -0
- data/lib/lutaml/uml/tagged_value.rb +21 -0
- data/lib/lutaml/uml/top_element.rb +7 -1
- data/lib/lutaml/uml/top_element_attribute.rb +4 -0
- data/lib/lutaml/uml/validation/document_structure_validator.rb +389 -0
- data/lib/lutaml/uml.rb +89 -45
- data/lib/lutaml/uml_repository/error_handler.rb +203 -0
- data/lib/lutaml/uml_repository/exporters/base_exporter.rb +61 -0
- data/lib/lutaml/uml_repository/exporters/json_exporter.rb +344 -0
- data/lib/lutaml/uml_repository/exporters/markdown_exporter.rb +598 -0
- data/lib/lutaml/uml_repository/index_builder.rb +460 -0
- data/lib/lutaml/uml_repository/lazy_repository.rb +238 -0
- data/lib/lutaml/uml_repository/package_exporter.rb +336 -0
- data/lib/lutaml/uml_repository/package_loader.rb +220 -0
- data/lib/lutaml/uml_repository/package_metadata.rb +77 -0
- data/lib/lutaml/uml_repository/presenters/association_presenter.rb +86 -0
- data/lib/lutaml/uml_repository/presenters/attribute_presenter.rb +101 -0
- data/lib/lutaml/uml_repository/presenters/class_presenter.rb +75 -0
- data/lib/lutaml/uml_repository/presenters/datatype_presenter.rb +108 -0
- data/lib/lutaml/uml_repository/presenters/diagram_presenter.rb +508 -0
- data/lib/lutaml/uml_repository/presenters/element_presenter.rb +92 -0
- data/lib/lutaml/uml_repository/presenters/enum_presenter.rb +83 -0
- data/lib/lutaml/uml_repository/presenters/package_presenter.rb +48 -0
- data/lib/lutaml/uml_repository/presenters/presenter_factory.rb +76 -0
- data/lib/lutaml/uml_repository/queries/association_query.rb +187 -0
- data/lib/lutaml/uml_repository/queries/base_query.rb +45 -0
- data/lib/lutaml/uml_repository/queries/class_query.rb +117 -0
- data/lib/lutaml/uml_repository/queries/diagram_query.rb +111 -0
- data/lib/lutaml/uml_repository/queries/inheritance_query.rb +259 -0
- data/lib/lutaml/uml_repository/queries/package_query.rb +239 -0
- data/lib/lutaml/uml_repository/queries/search_query.rb +357 -0
- data/lib/lutaml/uml_repository/query_dsl/conditions/base_condition.rb +28 -0
- data/lib/lutaml/uml_repository/query_dsl/conditions/block_condition.rb +46 -0
- data/lib/lutaml/uml_repository/query_dsl/conditions/hash_condition.rb +84 -0
- data/lib/lutaml/uml_repository/query_dsl/conditions/package_condition.rb +84 -0
- data/lib/lutaml/uml_repository/query_dsl/order.rb +90 -0
- data/lib/lutaml/uml_repository/query_dsl/query_builder.rb +296 -0
- data/lib/lutaml/uml_repository/repository.rb +764 -0
- data/lib/lutaml/uml_repository/repository_enhanced.rb +439 -0
- data/lib/lutaml/uml_repository/search_result.rb +86 -0
- data/lib/lutaml/uml_repository/static_site/configuration.rb +270 -0
- data/lib/lutaml/uml_repository/static_site/data_transformer.rb +967 -0
- data/lib/lutaml/uml_repository/static_site/generator.rb +401 -0
- data/lib/lutaml/uml_repository/static_site/id_generator.rb +115 -0
- data/lib/lutaml/uml_repository/static_site/search_index_builder.rb +317 -0
- data/lib/lutaml/uml_repository/static_site.rb +88 -0
- data/lib/lutaml/uml_repository/statistics_calculator.rb +334 -0
- data/lib/lutaml/uml_repository/validators/repository_validator.rb +404 -0
- data/lib/lutaml/uml_repository/web_ui/app.rb +144 -0
- data/lib/lutaml/uml_repository/web_ui/public/app.js +452 -0
- data/lib/lutaml/uml_repository/web_ui/public/styles.css +381 -0
- data/lib/lutaml/uml_repository/web_ui/views/index.erb +40 -0
- data/lib/lutaml/uml_repository.rb +97 -0
- data/lib/lutaml/version.rb +3 -1
- data/lib/lutaml/xmi/liquid_drops/association_drop.rb +60 -58
- data/lib/lutaml/xmi/liquid_drops/attribute_drop.rb +55 -53
- data/lib/lutaml/xmi/liquid_drops/cardinality_drop.rb +15 -13
- data/lib/lutaml/xmi/liquid_drops/connector_drop.rb +50 -46
- data/lib/lutaml/xmi/liquid_drops/constraint_drop.rb +19 -17
- data/lib/lutaml/xmi/liquid_drops/data_type_drop.rb +93 -90
- data/lib/lutaml/xmi/liquid_drops/dependency_drop.rb +26 -24
- data/lib/lutaml/xmi/liquid_drops/diagram_drop.rb +26 -24
- data/lib/lutaml/xmi/liquid_drops/enum_drop.rb +40 -37
- data/lib/lutaml/xmi/liquid_drops/enum_owned_literal_drop.rb +20 -18
- data/lib/lutaml/xmi/liquid_drops/generalization_attribute_drop.rb +64 -62
- data/lib/lutaml/xmi/liquid_drops/generalization_drop.rb +142 -140
- data/lib/lutaml/xmi/liquid_drops/klass_drop.rb +174 -170
- data/lib/lutaml/xmi/liquid_drops/operation_drop.rb +23 -21
- data/lib/lutaml/xmi/liquid_drops/package_drop.rb +95 -93
- data/lib/lutaml/xmi/liquid_drops/root_drop.rb +28 -25
- data/lib/lutaml/xmi/liquid_drops/source_target_drop.rb +39 -37
- data/lib/lutaml/xmi/parsers/xmi_base.rb +27 -17
- data/lib/lutaml/xmi/parsers/xml.rb +9 -9
- data/lib/lutaml/xmi.rb +37 -6
- data/lib/lutaml/xml/parsers/xml.rb +3 -1
- data/lib/lutaml/xml.rb +3 -1
- data/lib/lutaml.rb +14 -2
- data/lutaml.gemspec +16 -8
- data/plateau_all_packages.lur +0 -0
- data/templates/static_site/assets/scripts/app.js +45 -0
- data/templates/static_site/assets/scripts/core/state.js +419 -0
- data/templates/static_site/assets/scripts/core/utils.js +133 -0
- data/templates/static_site/assets/scripts/ui/details.js +74 -0
- data/templates/static_site/assets/scripts/ui/diagrams.js +345 -0
- data/templates/static_site/assets/scripts/ui/search.js +187 -0
- data/templates/static_site/assets/scripts/ui/sidebar.js +214 -0
- data/templates/static_site/assets/styles/00-variables.css +144 -0
- data/templates/static_site/assets/styles/01-reset.css +79 -0
- data/templates/static_site/assets/styles/02-base.css +149 -0
- data/templates/static_site/assets/styles/03-layout.css +171 -0
- data/templates/static_site/assets/styles/04-components.css +856 -0
- data/templates/static_site/assets/styles/05-utilities.css +89 -0
- data/templates/static_site/assets/styles/06-diagrams.css +277 -0
- data/templates/static_site/components/class_details.liquid +328 -0
- data/templates/static_site/components/content.liquid +508 -0
- data/templates/static_site/components/diagram_list.liquid +52 -0
- data/templates/static_site/components/diagram_viewer.liquid +71 -0
- data/templates/static_site/components/header.liquid +134 -0
- data/templates/static_site/components/package_details.liquid +119 -0
- data/templates/static_site/components/sidebar.liquid +46 -0
- data/templates/static_site/components/tree_node.liquid +81 -0
- data/templates/static_site/multi_file.liquid +46 -0
- data/templates/static_site/single_file.liquid +52 -0
- metadata +604 -31
- data/CODE_OF_CONDUCT.md +0 -74
- data/docs/lutaml-sysml.adoc +0 -10
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Lutaml
|
|
4
|
+
module UmlRepository
|
|
5
|
+
module Validators
|
|
6
|
+
# RepositoryValidator validates the consistency and integrity of a
|
|
7
|
+
# UML repository
|
|
8
|
+
#
|
|
9
|
+
# Performs comprehensive validation checks including:
|
|
10
|
+
# - Type reference validation (checking all attribute types exist)
|
|
11
|
+
# - Generalization reference validation (checking parent classes exist)
|
|
12
|
+
# - Circular inheritance detection
|
|
13
|
+
# - Association reference validation
|
|
14
|
+
# - Multiplicity validation
|
|
15
|
+
#
|
|
16
|
+
# @example Validating a repository
|
|
17
|
+
# validator = RepositoryValidator.new(document, indexes)
|
|
18
|
+
# result = validator.validate
|
|
19
|
+
# if result.valid?
|
|
20
|
+
# puts "Model is valid"
|
|
21
|
+
# else
|
|
22
|
+
# result.errors.each { |error| puts "ERROR: #{error}" }
|
|
23
|
+
# end
|
|
24
|
+
class RepositoryValidator
|
|
25
|
+
# Primitive types that don't need to be resolved
|
|
26
|
+
PRIMITIVE_TYPES = %w[
|
|
27
|
+
String Integer Boolean Date DateTime Float Double
|
|
28
|
+
Long Short Byte Char Time Decimal
|
|
29
|
+
UnlimitedNatural Real
|
|
30
|
+
].freeze
|
|
31
|
+
|
|
32
|
+
# @param document [Lutaml::Uml::Document] The UML document
|
|
33
|
+
# @param indexes [Hash] The repository indexes
|
|
34
|
+
def initialize(document, indexes)
|
|
35
|
+
@document = document
|
|
36
|
+
@indexes = indexes
|
|
37
|
+
@errors = []
|
|
38
|
+
@warnings = []
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Validate the repository and return results
|
|
42
|
+
#
|
|
43
|
+
# @param verbose [Boolean] Collect detailed validation information
|
|
44
|
+
# @return [ValidationResult] Validation results with errors and warnings
|
|
45
|
+
def validate(verbose: false) # rubocop:disable Metrics/MethodLength
|
|
46
|
+
@verbose = verbose
|
|
47
|
+
@validation_details = [] if verbose
|
|
48
|
+
|
|
49
|
+
check_type_references
|
|
50
|
+
check_generalization_references
|
|
51
|
+
# DISABLED: check_circular_inheritance - has bugs with name resolution
|
|
52
|
+
check_association_references
|
|
53
|
+
check_multiplicities
|
|
54
|
+
|
|
55
|
+
ValidationResult.new(
|
|
56
|
+
valid: @errors.empty?,
|
|
57
|
+
errors: @errors,
|
|
58
|
+
warnings: @warnings,
|
|
59
|
+
external_references: @external_references || [],
|
|
60
|
+
validation_details: @validation_details,
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
# Check that all attribute types reference existing classes or are
|
|
67
|
+
# primitives
|
|
68
|
+
def check_type_references # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
69
|
+
@external_references = []
|
|
70
|
+
|
|
71
|
+
@indexes[:qualified_names].each do |qname, klass| # rubocop:disable Metrics/BlockLength
|
|
72
|
+
next unless klass.is_a?(Lutaml::Uml::Class)
|
|
73
|
+
next unless klass.attributes
|
|
74
|
+
|
|
75
|
+
# Extract current package path from qualified name
|
|
76
|
+
current_package_path = extract_package_path(qname)
|
|
77
|
+
|
|
78
|
+
# Collect detailed validation info for this class if verbose
|
|
79
|
+
class_details = { class_name: qname, attributes: [] } if @verbose
|
|
80
|
+
|
|
81
|
+
klass.attributes.each do |attr| # rubocop:disable Metrics/BlockLength
|
|
82
|
+
next unless attr.type
|
|
83
|
+
|
|
84
|
+
is_primitive = primitive_type?(attr.type)
|
|
85
|
+
|
|
86
|
+
# Try to resolve the type name
|
|
87
|
+
resolved_type = if is_primitive
|
|
88
|
+
nil
|
|
89
|
+
else
|
|
90
|
+
resolve_type_name(attr.type,
|
|
91
|
+
current_package_path)
|
|
92
|
+
end
|
|
93
|
+
is_valid = is_primitive || !resolved_type.nil?
|
|
94
|
+
|
|
95
|
+
# Collect verbose info
|
|
96
|
+
if @verbose
|
|
97
|
+
class_details[:attributes] << {
|
|
98
|
+
attribute_name: attr.name,
|
|
99
|
+
type_value: attr.type,
|
|
100
|
+
resolved_to: resolved_type,
|
|
101
|
+
valid: is_valid,
|
|
102
|
+
is_primitive: is_primitive,
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
next if is_valid
|
|
107
|
+
|
|
108
|
+
# Track external reference
|
|
109
|
+
@external_references << {
|
|
110
|
+
class_name: qname,
|
|
111
|
+
attribute_name: attr.name,
|
|
112
|
+
referenced_type: attr.type,
|
|
113
|
+
context: "attribute type",
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@errors << "Unresolved type reference: '#{attr.type}' in " \
|
|
117
|
+
"#{qname}.#{attr.name}"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
if @verbose && class_details[:attributes].any?
|
|
121
|
+
@validation_details << class_details
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Check that all generalization references point to existing classes
|
|
127
|
+
def check_generalization_references
|
|
128
|
+
@indexes[:inheritance_graph].each do |parent_qname, children|
|
|
129
|
+
# Check if parent exists
|
|
130
|
+
unless @indexes[:qualified_names].key?(parent_qname)
|
|
131
|
+
children.each do |child_qname|
|
|
132
|
+
@errors << "Generalization references non-existent parent: " \
|
|
133
|
+
"#{parent_qname} from #{child_qname}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Detect circular inheritance relationships
|
|
140
|
+
def check_circular_inheritance
|
|
141
|
+
visited = {}
|
|
142
|
+
|
|
143
|
+
@indexes[:inheritance_graph].each_key do |parent_qname|
|
|
144
|
+
cycle = find_cycle(parent_qname, visited, [])
|
|
145
|
+
if cycle
|
|
146
|
+
@errors << "Circular inheritance detected: #{cycle.join(' -> ')}"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Check that all association ends reference existing classes
|
|
152
|
+
def check_association_references # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
153
|
+
@indexes[:qualified_names].each do |qname, klass|
|
|
154
|
+
next unless klass.is_a?(Lutaml::Uml::Class)
|
|
155
|
+
next unless klass.associations
|
|
156
|
+
|
|
157
|
+
klass.associations.each do |assoc|
|
|
158
|
+
# Check member_end references
|
|
159
|
+
if assoc.respond_to?(:member_end) && assoc.member_end
|
|
160
|
+
check_association_end_type(assoc.member_end, qname)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Check owned_end references
|
|
164
|
+
if assoc.respond_to?(:owned_end) && assoc.owned_end
|
|
165
|
+
check_association_end_type(assoc.owned_end, qname)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Check association end type references
|
|
172
|
+
#
|
|
173
|
+
# @param ends [Array, Object] Association ends to check
|
|
174
|
+
# @param source_qname [String] Source class qualified name
|
|
175
|
+
def check_association_end_type(ends, source_qname) # rubocop:disable Metrics/CyclomaticComplexity
|
|
176
|
+
ends_array = ends.is_a?(Array) ? ends : [ends]
|
|
177
|
+
|
|
178
|
+
ends_array.each do |end_obj|
|
|
179
|
+
next unless end_obj.respond_to?(:type)
|
|
180
|
+
next unless end_obj.type
|
|
181
|
+
|
|
182
|
+
type_name = end_obj.type
|
|
183
|
+
type_name = type_name.name if type_name.respond_to?(:name)
|
|
184
|
+
|
|
185
|
+
next if @indexes[:qualified_names].key?(type_name)
|
|
186
|
+
|
|
187
|
+
@warnings << "Association end references potentially " \
|
|
188
|
+
"unresolved type: '#{type_name}' from #{source_qname}"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Check multiplicity values are valid
|
|
193
|
+
def check_multiplicities # rubocop:disable Metrics/CyclomaticComplexity
|
|
194
|
+
@indexes[:qualified_names].each do |qname, klass|
|
|
195
|
+
next unless klass.is_a?(Lutaml::Uml::Class)
|
|
196
|
+
next unless klass.attributes
|
|
197
|
+
|
|
198
|
+
klass.attributes.each do |attr|
|
|
199
|
+
next unless attr.respond_to?(:cardinality)
|
|
200
|
+
next unless attr.cardinality
|
|
201
|
+
|
|
202
|
+
cardinality = attr.cardinality
|
|
203
|
+
check_cardinality_value(cardinality, qname, attr.name)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Check a cardinality value is valid
|
|
209
|
+
#
|
|
210
|
+
# @param cardinality [Object] Cardinality object
|
|
211
|
+
# @param class_qname [String] Class qualified name
|
|
212
|
+
# @param attr_name [String] Attribute name
|
|
213
|
+
def check_cardinality_value(cardinality, class_qname, attr_name) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
214
|
+
min_val = extract_min_value(cardinality)
|
|
215
|
+
max_val = extract_max_value(cardinality)
|
|
216
|
+
|
|
217
|
+
return unless min_val || max_val
|
|
218
|
+
|
|
219
|
+
# Check min is not negative
|
|
220
|
+
if min_val.is_a?(Integer) && min_val.negative?
|
|
221
|
+
@errors << "Invalid multiplicity: min value #{min_val} is " \
|
|
222
|
+
"negative in #{class_qname}.#{attr_name}"
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Check max is not less than min (unless it's unlimited)
|
|
226
|
+
if min_val && max_val.is_a?(Integer) && (max_val < min_val)
|
|
227
|
+
@errors << "Invalid multiplicity: max (#{max_val}) < min " \
|
|
228
|
+
"(#{min_val}) in #{class_qname}.#{attr_name}"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Extract min value from cardinality
|
|
233
|
+
#
|
|
234
|
+
# @param cardinality [Object] Cardinality object
|
|
235
|
+
# @return [Integer, nil] Min value
|
|
236
|
+
def extract_min_value(cardinality)
|
|
237
|
+
return nil unless cardinality.respond_to?(:min)
|
|
238
|
+
|
|
239
|
+
min_val = cardinality.min
|
|
240
|
+
return nil unless min_val
|
|
241
|
+
|
|
242
|
+
min_val.is_a?(Hash) ? min_val["value"] : min_val
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Extract max value from cardinality
|
|
246
|
+
#
|
|
247
|
+
# @param cardinality [Object] Cardinality object
|
|
248
|
+
# @return [Integer, String, nil] Max value (could be "*" for unlimited)
|
|
249
|
+
def extract_max_value(cardinality)
|
|
250
|
+
return nil unless cardinality.respond_to?(:max)
|
|
251
|
+
|
|
252
|
+
max_val = cardinality.max
|
|
253
|
+
return nil unless max_val
|
|
254
|
+
|
|
255
|
+
max_val.is_a?(Hash) ? max_val["value"] : max_val
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Find a cycle in the inheritance graph starting from a node
|
|
259
|
+
#
|
|
260
|
+
# @param qname [String] Starting qualified name
|
|
261
|
+
# @param visited [Hash] Visited nodes state
|
|
262
|
+
# @param path [Array] Current path
|
|
263
|
+
# @return [Array, nil] Cycle path if found, nil otherwise
|
|
264
|
+
def find_cycle(qname, visited, path) # rubocop:disable Metrics/MethodLength
|
|
265
|
+
return nil if visited[qname] == :permanent
|
|
266
|
+
return path + [qname] if path.include?(qname)
|
|
267
|
+
|
|
268
|
+
visited[qname] = :temporary
|
|
269
|
+
path.push(qname)
|
|
270
|
+
|
|
271
|
+
children = @indexes[:inheritance_graph][qname] || []
|
|
272
|
+
children.each do |child_qname|
|
|
273
|
+
cycle = find_cycle(child_qname, visited, path)
|
|
274
|
+
return cycle if cycle
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
path.pop
|
|
278
|
+
visited[qname] = :permanent
|
|
279
|
+
nil
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# Extract package path from qualified name
|
|
283
|
+
#
|
|
284
|
+
# @param qname [String] Qualified name like "ModelRoot::Package::Class"
|
|
285
|
+
# @return [String] Package path like "ModelRoot::Package"
|
|
286
|
+
def extract_package_path(qname)
|
|
287
|
+
parts = qname.split("::")
|
|
288
|
+
parts.size > 1 ? parts[0..-2].join("::") : "ModelRoot"
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# Resolve a type name to its fully qualified name
|
|
292
|
+
#
|
|
293
|
+
# @param type_name [String] Type name to resolve
|
|
294
|
+
# @param current_package_path [String] Current package context
|
|
295
|
+
# @return [String, nil] Resolved qualified name or nil if not found
|
|
296
|
+
def resolve_type_name(type_name, current_package_path)
|
|
297
|
+
# Already qualified and exists?
|
|
298
|
+
return type_name if @indexes[:qualified_names].key?(type_name)
|
|
299
|
+
|
|
300
|
+
# Try in current package
|
|
301
|
+
local_qname = "#{current_package_path}::#{type_name}"
|
|
302
|
+
return local_qname if @indexes[:qualified_names].key?(local_qname)
|
|
303
|
+
|
|
304
|
+
# Try to find in all qualified names (simple name match)
|
|
305
|
+
@indexes[:qualified_names].each_key do |qname|
|
|
306
|
+
return qname if qname.end_with?("::#{type_name}")
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
nil
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Check if a type is a primitive type
|
|
313
|
+
#
|
|
314
|
+
# @param type [String] Type name
|
|
315
|
+
# @return [Boolean] True if primitive type
|
|
316
|
+
def primitive_type?(type)
|
|
317
|
+
PRIMITIVE_TYPES.include?(type)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# ValidationResult encapsulates the results of repository validation
|
|
322
|
+
#
|
|
323
|
+
# @example Checking validation results
|
|
324
|
+
# result = validator.validate
|
|
325
|
+
# puts "Valid: #{result.valid?}"
|
|
326
|
+
# puts "Errors: #{result.errors.size}"
|
|
327
|
+
# puts "Warnings: #{result.warnings.size}"
|
|
328
|
+
# puts "External refs: #{result.external_references.size}"
|
|
329
|
+
class ValidationResult
|
|
330
|
+
# @return [Array<String>] Validation errors
|
|
331
|
+
attr_reader :errors
|
|
332
|
+
|
|
333
|
+
# @return [Array<String>] Validation warnings
|
|
334
|
+
attr_reader :warnings
|
|
335
|
+
|
|
336
|
+
# @return [Array<Hash>] External type references
|
|
337
|
+
attr_reader :external_references
|
|
338
|
+
|
|
339
|
+
# @return [Array<Hash>] Detailed validation information
|
|
340
|
+
attr_reader :validation_details
|
|
341
|
+
|
|
342
|
+
# @param valid [Boolean] Whether validation passed
|
|
343
|
+
# @param errors [Array<String>] Validation errors
|
|
344
|
+
# @param warnings [Array<String>] Validation warnings
|
|
345
|
+
# @param external_references [Array<Hash>] External type references
|
|
346
|
+
# @param validation_details [Array<Hash>, nil] Detailed validation
|
|
347
|
+
# information
|
|
348
|
+
def initialize(
|
|
349
|
+
valid:, errors:, warnings:, external_references: [],
|
|
350
|
+
validation_details: nil
|
|
351
|
+
)
|
|
352
|
+
@valid = valid
|
|
353
|
+
@errors = errors.freeze
|
|
354
|
+
@warnings = warnings.freeze
|
|
355
|
+
@external_references = external_references.freeze
|
|
356
|
+
@validation_details = validation_details&.freeze
|
|
357
|
+
freeze
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# Check if validation passed (no errors)
|
|
361
|
+
#
|
|
362
|
+
# @return [Boolean] True if no errors
|
|
363
|
+
def valid?
|
|
364
|
+
@valid
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
# Check if there are any warnings
|
|
368
|
+
#
|
|
369
|
+
# @return [Boolean] True if warnings present
|
|
370
|
+
def has_warnings?
|
|
371
|
+
!@warnings.empty?
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# Check if there are any external references
|
|
375
|
+
#
|
|
376
|
+
# @return [Boolean] True if external references found
|
|
377
|
+
def has_external_references?
|
|
378
|
+
!@external_references.empty?
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
# Get total issue count (errors + warnings)
|
|
382
|
+
#
|
|
383
|
+
# @return [Integer] Total number of issues
|
|
384
|
+
def issue_count
|
|
385
|
+
@errors.size + @warnings.size
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
# Get a summary of validation results
|
|
389
|
+
#
|
|
390
|
+
# @return [String] Summary string
|
|
391
|
+
def summary
|
|
392
|
+
if valid? && !has_warnings?
|
|
393
|
+
"Validation passed: no issues found"
|
|
394
|
+
elsif valid?
|
|
395
|
+
"Validation passed with #{@warnings.size} warning(s)"
|
|
396
|
+
else
|
|
397
|
+
"Validation failed with #{@errors.size} error(s) and " \
|
|
398
|
+
"#{@warnings.size} warning(s)"
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "sinatra/base"
|
|
4
|
+
require "json"
|
|
5
|
+
require "liquid"
|
|
6
|
+
require_relative "../static_site"
|
|
7
|
+
|
|
8
|
+
module Lutaml
|
|
9
|
+
module Xmi
|
|
10
|
+
module WebUi
|
|
11
|
+
# Sinatra web application for browsing UML models.
|
|
12
|
+
#
|
|
13
|
+
# Serves the modern SPA interface with JSON API endpoints and lunr.js
|
|
14
|
+
# search.
|
|
15
|
+
# Uses shared Liquid templates with the static site generator.
|
|
16
|
+
#
|
|
17
|
+
# @example Starting the server
|
|
18
|
+
# Lutaml::Xmi::WebUi::App.serve("model.lur", port: 3000)
|
|
19
|
+
class App < Sinatra::Base
|
|
20
|
+
enable :logging
|
|
21
|
+
|
|
22
|
+
# Serve the SPA (using shared Liquid template)
|
|
23
|
+
get "/" do # rubocop:disable Metrics/BlockLength
|
|
24
|
+
content_type :html
|
|
25
|
+
|
|
26
|
+
# Use the same multi_file.liquid template as static generator
|
|
27
|
+
# but with apiMode: true to use JSON endpoints
|
|
28
|
+
template_path = File.expand_path(
|
|
29
|
+
File.join(
|
|
30
|
+
__dir__,
|
|
31
|
+
"..", "..", "..", "..", "templates", "static_site"
|
|
32
|
+
),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
Liquid::Template.file_system = Liquid::LocalFileSystem.new(template_path)
|
|
36
|
+
|
|
37
|
+
template_content = File.read(File.join(template_path,
|
|
38
|
+
"multi_file.liquid"))
|
|
39
|
+
template = Liquid::Template.parse(template_content)
|
|
40
|
+
|
|
41
|
+
context = {
|
|
42
|
+
"config" => {
|
|
43
|
+
"mode" => "multi_file",
|
|
44
|
+
"title" => "UML Repository Explorer (Live)",
|
|
45
|
+
"description" => "Live browser for UML models",
|
|
46
|
+
"apiMode" => true, # KEY: Use API endpoints instead of static JSON
|
|
47
|
+
"theme" => "light",
|
|
48
|
+
},
|
|
49
|
+
"buildInfo" => {
|
|
50
|
+
"timestamp" => Time.now.utc.iso8601,
|
|
51
|
+
"generator" => "LutaML Live Web UI v2.0",
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
template.render(context)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# API: Full data model (replaces data/model.json in static mode)
|
|
59
|
+
get "/api/data" do
|
|
60
|
+
content_type :json
|
|
61
|
+
|
|
62
|
+
# Use shared DataTransformer
|
|
63
|
+
transformer = UmlRepository::StaticSite::DataTransformer.new(repository)
|
|
64
|
+
transformer.transform.to_json
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# API: Search index (replaces data/search.json in static mode)
|
|
68
|
+
get "/api/search/index" do
|
|
69
|
+
content_type :json
|
|
70
|
+
|
|
71
|
+
# Use shared SearchIndexBuilder
|
|
72
|
+
builder = UmlRepository::StaticSite::SearchIndexBuilder.new(repository)
|
|
73
|
+
builder.build.to_json
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# API: Package details (on-demand, optional optimization)
|
|
77
|
+
get "/api/packages/:id" do
|
|
78
|
+
content_type :json
|
|
79
|
+
params[:id]
|
|
80
|
+
|
|
81
|
+
# Find package by generated ID
|
|
82
|
+
# This would require reverse lookup from ID to package
|
|
83
|
+
# For now, use the full data endpoint
|
|
84
|
+
halt 501, { error: "On-demand package loading not yet implemented. " \
|
|
85
|
+
"Use /api/data" }.to_json
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# API: Class details (on-demand, optional optimization)
|
|
89
|
+
get "/api/classes/:id" do
|
|
90
|
+
content_type :json
|
|
91
|
+
params[:id]
|
|
92
|
+
|
|
93
|
+
# Find class by generated ID
|
|
94
|
+
# This would require reverse lookup from ID to class
|
|
95
|
+
# For now, use the full data endpoint
|
|
96
|
+
halt 501, { error: "On-demand class loading not yet implemented. " \
|
|
97
|
+
"Use /api/data" }.to_json
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Start the web server
|
|
101
|
+
def self.serve(lur_path, port: 3000, host: "localhost") # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
102
|
+
repo = if File.extname(lur_path) == ".lur"
|
|
103
|
+
UmlRepository::Repository.from_package(lur_path)
|
|
104
|
+
else
|
|
105
|
+
UmlRepository::Repository.from_xmi(lur_path)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
set :repository, repo
|
|
109
|
+
set :port, port
|
|
110
|
+
set :bind, host
|
|
111
|
+
|
|
112
|
+
puts ""
|
|
113
|
+
puts "╔═══════════════════════════════════════════════════════════╗"
|
|
114
|
+
puts "║ LutaML UML Browser - Web Server ║"
|
|
115
|
+
puts "╚═══════════════════════════════════════════════════════════╝"
|
|
116
|
+
puts ""
|
|
117
|
+
puts " Loading: #{File.basename(lur_path)}"
|
|
118
|
+
puts " Server: http://#{host}:#{port}"
|
|
119
|
+
puts ""
|
|
120
|
+
puts " Features:"
|
|
121
|
+
puts " • Modern SPA interface"
|
|
122
|
+
puts " • Live data via JSON API"
|
|
123
|
+
puts " • Full-text search with lunr.js"
|
|
124
|
+
puts " • Dark/light themes"
|
|
125
|
+
puts " • Responsive design"
|
|
126
|
+
puts ""
|
|
127
|
+
puts " Press Ctrl+C to stop"
|
|
128
|
+
puts ""
|
|
129
|
+
puts "─" * 60
|
|
130
|
+
puts ""
|
|
131
|
+
|
|
132
|
+
run!
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
# Get the repository from settings
|
|
138
|
+
def repository
|
|
139
|
+
settings.repository
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|