From 2786ae299e66075014ff5e7d569f2099381f1457 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 3 Feb 2021 06:09:16 +0100 Subject: [PATCH 001/280] Add initial project structure --- .gitignore | 15 + LICENSE | 165 +++++++ build.gradle.kts | 62 +++ gradle.properties | 1 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 185 +++++++ gradlew.bat | 89 ++++ settings.gradle.kts | 1 + .../java/de/atextor/turtle/formatter/FMT.java | 7 + .../turtle/formatter/FormattingStyle.java | 245 +++++++++ .../turtle/formatter/TurtleFormatter.java | 467 ++++++++++++++++++ .../turtle/formatter/TurtleFormatterTest.java | 204 ++++++++ 13 files changed, 1446 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 build.gradle.kts create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle.kts create mode 100644 src/main/java/de/atextor/turtle/formatter/FMT.java create mode 100644 src/main/java/de/atextor/turtle/formatter/FormattingStyle.java create mode 100644 src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java create mode 100644 src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3416e327 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build + +.idea +out/ +catalog-v*.xml + +.cache + +**/.jqwik-database + +**/src/generated/java \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0a041280 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..5b5b8e7f --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,62 @@ +import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask + +plugins { + java + jacoco + id("com.github.ben-manes.versions") version "0.33.0" + id("com.adarshr.test-logger") version "2.1.0" + id("io.franzbecker.gradle-lombok") version "4.0.0" +} + +repositories { + jcenter() + maven(url = "https://jitpack.io") +} + +dependencies { + implementation("org.apache.jena:jena:3.16.0") + implementation("org.apache.jena:jena-core:3.16.0") + implementation("io.vavr:vavr:0.10.3") + implementation("org.slf4j:slf4j-api:1.7.30") + + testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0") + testImplementation("org.assertj:assertj-core:3.17.2") + testImplementation("net.jqwik:jqwik:1.3.6") + + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0") +} + +jacoco { + toolVersion = "0.8.6" +} + +fun isNonStable(version: String): Boolean { + val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.toUpperCase().contains(it) } + val regex = "^[0-9,.v-]+(-r)?$".toRegex() + val isStable = stableKeyword || regex.matches(version) + return isStable.not() +} + +tasks.named("dependencyUpdates", DependencyUpdatesTask::class.java).configure { + rejectVersionIf { + isNonStable(candidate.version) + } +} + +tasks { + compileJava { + options.encoding = "UTF-8" + sourceCompatibility = "15" + } + + compileTestJava { + options.encoding = "UTF-8" + sourceCompatibility = "15" + } + + test { + useJUnitPlatform() + ignoreFailures = false + failFast = true + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..4b72665b --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +version=snapshot \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ zw`1S}(D?mUXu_C{wupRS-jiX~w=Uqqhf|Vb3Cm9L=T+w91Cu^ z*&Ty%sN?x*h~mJc4g~k{xD4ZmF%FXZNC;oVDwLZ_WvrnzY|{v8hc1nmx4^}Z;yriXsAf+Lp+OFLbR!&Ox?xABwl zu8w&|5pCxmu#$?Cv2_-Vghl2LZ6m7}VLEfR5o2Ou$x02uA-%QB2$c(c1rH3R9hesc zfpn#oqpbKuVsdfV#cv@5pV4^f_!WS+F>SV6N0JQ9E!T90EX((_{bSSFv9ld%I0&}9 zH&Jd4MEX1e0iqDtq~h?DBrxQX1iI0lIs<|kB$Yrh&cpeK0-^K%=FBsCBT46@h#yi!AyDq1V(#V}^;{{V*@T4WJ&U-NTq43w=|K>z8%pr_nC>%C(Wa_l78Ufib$r8Od)IIN=u>417 z`Hl{9A$mI5A(;+-Q&$F&h-@;NR>Z<2U;Y21>>Z;s@0V@SbkMQQj%_;~+qTuQ?c|AV zcWm3XZQHhP&R%QWarS%mJ!9R^&!_)*s(v+VR@I#QrAT}`17Y+l<`b-nvmDNW`De%y zrwTZ9EJrj1AFA>B`1jYDow}~*dfPs}IZMO3=a{Fy#IOILc8F0;JS4x(k-NSpbN@qM z`@aE_e}5{!$v3+qVs7u?sOV(y@1Os*Fgu`fCW9=G@F_#VQ%xf$hj0~wnnP0$hFI+@ zkQj~v#V>xn)u??YutKsX>pxKCl^p!C-o?+9;!Nug^ z{rP!|+KsP5%uF;ZCa5F;O^9TGac=M|=V z_H(PfkV1rz4jl?gJ(ArXMyWT4y(86d3`$iI4^l9`vLdZkzpznSd5Ikfrs8qcSy&>z zTIZgWZGXw0n9ibQxYWE@gI0(3#KA-dAdPcsL_|hg2@~C!VZDM}5;v_Nykfq!*@*Zf zE_wVgx82GMDryKO{U{D>vSzSc%B~|cjDQrt5BN=Ugpsf8H8f1lR4SGo#hCuXPL;QQ z#~b?C4MoepT3X`qdW2dNn& zo8)K}%Lpu>0tQei+{>*VGErz|qjbK#9 zvtd8rcHplw%YyQCKR{kyo6fgg!)6tHUYT(L>B7er5)41iG`j$qe*kSh$fY!PehLcD zWeKZHn<492B34*JUQh=CY1R~jT9Jt=k=jCU2=SL&&y5QI2uAG2?L8qd2U(^AW#{(x zThSy=C#>k+QMo^7caQcpU?Qn}j-`s?1vXuzG#j8(A+RUAY})F@=r&F(8nI&HspAy4 z4>(M>hI9c7?DCW8rw6|23?qQMSq?*Vx?v30U%luBo)B-k2mkL)Ljk5xUha3pK>EEj z@(;tH|M@xkuN?gsz;*bygizwYR!6=(Xgcg^>WlGtRYCozY<rFX2E>kaZo)O<^J7a`MX8Pf`gBd4vrtD|qKn&B)C&wp0O-x*@-|m*0egT=-t@%dD zgP2D+#WPptnc;_ugD6%zN}Z+X4=c61XNLb7L1gWd8;NHrBXwJ7s0ce#lWnnFUMTR& z1_R9Fin4!d17d4jpKcfh?MKRxxQk$@)*hradH2$3)nyXep5Z;B z?yX+-Bd=TqO2!11?MDtG0n(*T^!CIiF@ZQymqq1wPM_X$Iu9-P=^}v7npvvPBu!d$ z7K?@CsA8H38+zjA@{;{kG)#AHME>Ix<711_iQ@WWMObXyVO)a&^qE1GqpP47Q|_AG zP`(AD&r!V^MXQ^e+*n5~Lp9!B+#y3#f8J^5!iC@3Y@P`;FoUH{G*pj*q7MVV)29+j z>BC`a|1@U_v%%o9VH_HsSnM`jZ-&CDvbiqDg)tQEnV>b%Ptm)T|1?TrpIl)Y$LnG_ zzKi5j2Fx^K^PG1=*?GhK;$(UCF-tM~^=Z*+Wp{FSuy7iHt9#4n(sUuHK??@v+6*|10Csdnyg9hAsC5_OrSL;jVkLlf zHXIPukLqbhs~-*oa^gqgvtpgTk_7GypwH><53riYYL*M=Q@F-yEPLqQ&1Sc zZB%w}T~RO|#jFjMWcKMZccxm-SL)s_ig?OC?y_~gLFj{n8D$J_Kw%{r0oB8?@dWzn zB528d-wUBQzrrSSLq?fR!K%59Zv9J4yCQhhDGwhptpA5O5U?Hjqt>8nOD zi{)0CI|&Gu%zunGI*XFZh(ix)q${jT8wnnzbBMPYVJc4HX*9d^mz|21$=R$J$(y7V zo0dxdbX3N#=F$zjstTf*t8vL)2*{XH!+<2IJ1VVFa67|{?LP&P41h$2i2;?N~RA30LV`BsUcj zfO9#Pg1$t}7zpv#&)8`mis3~o+P(DxOMgz-V*(?wWaxi?R=NhtW}<#^Z?(BhSwyar zG|A#Q7wh4OfK<|DAcl9THc-W4*>J4nTevsD%dkj`U~wSUCh15?_N@uMdF^Kw+{agk zJ`im^wDqj`Ev)W3k3stasP`88-M0ZBs7;B6{-tSm3>I@_e-QfT?7|n0D~0RRqDb^G zyHb=is;IwuQ&ITzL4KsP@Z`b$d%B0Wuhioo1CWttW8yhsER1ZUZzA{F*K=wmi-sb#Ju+j z-l@In^IKnb{bQG}Ps>+Vu_W#grNKNGto+yjA)?>0?~X`4I3T@5G1)RqGUZuP^NJCq&^HykuYtMDD8qq+l8RcZNJsvN(10{ zQ1$XcGt}QH-U^WU!-wRR1d--{B$%vY{JLWIV%P4-KQuxxDeJaF#{eu&&r!3Qu{w}0f--8^H|KwE>)ORrcR+2Qf zb})DRcH>k0zWK8@{RX}NYvTF;E~phK{+F;MkIP$)T$93Ba2R2TvKc>`D??#mv9wg$ zd~|-`Qx5LwwsZ2hb*Rt4S9dsF%Cny5<1fscy~)d;0m2r$f=83<->c~!GNyb!U)PA; zq^!`@@)UaG)Ew(9V?5ZBq#c%dCWZrplmuM`o~TyHjAIMh0*#1{B>K4po-dx$Tk-Cq z=WZDkP5x2W&Os`N8KiYHRH#UY*n|nvd(U>yO=MFI-2BEp?x@=N<~CbLJBf6P)}vLS?xJXYJ2^<3KJUdrwKnJnTp{ zjIi|R=L7rn9b*D#Xxr4*R<3T5AuOS+#U8hNlfo&^9JO{VbH!v9^JbK=TCGR-5EWR@ zN8T-_I|&@A}(hKeL4_*eb!1G8p~&_Im8|wc>Cdir+gg90n1dw?QaXcx6Op_W1r=axRw>4;rM*UOpT#Eb9xU1IiWo@h?|5uP zka>-XW0Ikp@dIe;MN8B01a7+5V@h3WN{J=HJ*pe0uwQ3S&MyWFni47X32Q7SyCTNQ z+sR!_9IZa5!>f&V$`q!%H8ci!a|RMx5}5MA_kr+bhtQy{-^)(hCVa@I!^TV4RBi zAFa!Nsi3y37I5EK;0cqu|9MRj<^r&h1lF}u0KpKQD^5Y+LvFEwM zLU@@v4_Na#Axy6tn3P%sD^5P#<7F;sd$f4a7LBMk zGU^RZHBcxSA%kCx*eH&wgA?Qwazm8>9SCSz_!;MqY-QX<1@p$*T8lc?@`ikEqJ>#w zcG``^CoFMAhdEXT9qt47g0IZkaU)4R7wkGs^Ax}usqJ5HfDYAV$!=6?>J6+Ha1I<5 z|6=9soU4>E))tW$<#>F ziZ$6>KJf0bPfbx_)7-}tMINlc=}|H+$uX)mhC6-Hz+XZxsKd^b?RFB6et}O#+>Wmw9Ec9) z{q}XFWp{3@qmyK*Jvzpyqv57LIR;hPXKsrh{G?&dRjF%Zt5&m20Ll?OyfUYC3WRn{cgQ?^V~UAv+5 z&_m#&nIwffgX1*Z2#5^Kl4DbE#NrD&Hi4|7SPqZ}(>_+JMz=s|k77aEL}<=0Zfb)a z%F(*L3zCA<=xO)2U3B|pcTqDbBoFp>QyAEU(jMu8(jLA61-H!ucI804+B!$E^cQQa z)_ERrW3g!B9iLb3nn3dlkvD7KsY?sRvls3QC0qPi>o<)GHx%4Xb$5a3GBTJ(k@`e@ z$RUa^%S15^1oLEmA=sayrP5;9qtf!Z1*?e$ORVPsXpL{jL<6E)0sj&swP3}NPmR%FM?O>SQgN5XfHE< zo(4#Cv11(%Nnw_{_Ro}r6=gKd{k?NebJ~<~Kv0r(r0qe4n3LFx$5%x(BKvrz$m?LG zjLIc;hbj0FMdb9aH9Lpsof#yG$(0sG2%RL;d(n>;#jb!R_+dad+K;Ccw!|RY?uS(a zj~?=&M!4C(5LnlH6k%aYvz@7?xRa^2gml%vn&eKl$R_lJ+e|xsNfXzr#xuh(>`}9g zLHSyiFwK^-p!;p$yt7$F|3*IfO3Mlu9e>Dpx8O`37?fA`cj`C0B-m9uRhJjs^mRp# zWB;Aj6|G^1V6`jg7#7V9UFvnB4((nIwG?k%c7h`?0tS8J3Bn0t#pb#SA}N-|45$-j z$R>%7cc2ebAClXc(&0UtHX<>pd)akR3Kx_cK+n<}FhzmTx!8e9^u2e4%x{>T6pQ`6 zO182bh$-W5A3^wos0SV_TgPmF4WUP-+D25KjbC{y_6W_9I2_vNKwU(^qSdn&>^=*t z&uvp*@c8#2*paD!ZMCi3;K{Na;I4Q35zw$YrW5U@Kk~)&rw;G?d7Q&c9|x<Hg|CNMsxovmfth*|E*GHezPTWa^Hd^F4!B3sF;)? z(NaPyAhocu1jUe(!5Cy|dh|W2=!@fNmuNOzxi^tE_jAtzNJ0JR-avc_H|ve#KO}#S z#a(8secu|^Tx553d4r@3#6^MHbH)vmiBpn0X^29xEv!Vuh1n(Sr5I0V&`jA2;WS|Y zbf0e}X|)wA-Pf5gBZ>r4YX3Mav1kKY(ulAJ0Q*jB)YhviHK)w!TJsi3^dMa$L@^{` z_De`fF4;M87vM3Ph9SzCoCi$#Fsd38u!^0#*sPful^p5oI(xGU?yeYjn;Hq1!wzFk zG&2w}W3`AX4bxoVm03y>ts{KaDf!}b&7$(P4KAMP=vK5?1In^-YYNtx1f#}+2QK@h zeSeAI@E6Z8a?)>sZ`fbq9_snl6LCu6g>o)rO;ijp3|$vig+4t} zylEo7$SEW<_U+qgVcaVhk+4k+C9THI5V10qV*dOV6pPtAI$)QN{!JRBKh-D zk2^{j@bZ}yqW?<#VVuI_27*cI-V~sJiqQv&m07+10XF+#ZnIJdr8t`9s_EE;T2V;B z4UnQUH9EdX%zwh-5&wflY#ve!IWt0UE-My3?L#^Bh%kcgP1q{&26eXLn zTkjJ*w+(|_>Pq0v8{%nX$QZbf)tbJaLY$03;MO=Ic-uqYUmUCuXD>J>o6BCRF=xa% z3R4SK9#t1!K4I_d>tZgE>&+kZ?Q}1qo4&h%U$GfY058s%*=!kac{0Z+4Hwm!)pFLR zJ+5*OpgWUrm0FPI2ib4NPJ+Sk07j(`diti^i#kh&f}i>P4~|d?RFb#!JN)~D@)beox}bw?4VCf^y*`2{4`-@%SFTry2h z>9VBc9#JxEs1+0i2^LR@B1J`B9Ac=#FW=(?2;5;#U$0E0UNag_!jY$&2diQk_n)bT zl5Me_SUvqUjwCqmVcyb`igygB_4YUB*m$h5oeKv3uIF0sk}~es!{D>4r%PC*F~FN3owq5e0|YeUTSG#Vq%&Gk7uwW z0lDo#_wvflqHeRm*}l?}o;EILszBt|EW*zNPmq#?4A+&i0xx^?9obLyY4xx=Y9&^G;xYXYPxG)DOpPg!i_Ccl#3L}6xAAZzNhPK1XaC_~ z!A|mlo?Be*8Nn=a+FhgpOj@G7yYs(Qk(8&|h@_>w8Y^r&5nCqe0V60rRz?b5%J;GYeBqSAjo|K692GxD4` zRZyM2FdI+-jK2}WAZTZ()w_)V{n5tEb@>+JYluDozCb$fA4H)$bzg(Ux{*hXurjO^ zwAxc+UXu=&JV*E59}h3kzQPG4M)X8E*}#_&}w*KEgtX)cU{vm9b$atHa;s>| z+L6&cn8xUL*OSjx4YGjf6{Eq+Q3{!ZyhrL&^6Vz@jGbI%cAM9GkmFlamTbcQGvOlL zmJ?(FI)c86=JEs|*;?h~o)88>12nXlpMR4@yh%qdwFNpct;vMlc=;{FSo*apJ;p}! zAX~t;3tb~VuP|ZW;z$=IHf->F@Ml)&-&Bnb{iQyE#;GZ@C$PzEf6~q}4D>9jic@mTO5x76ulDz@+XAcm35!VSu zT*Gs>;f0b2TNpjU_BjHZ&S6Sqk6V1370+!eppV2H+FY!q*n=GHQ!9Rn6MjY!Jc77A zG7Y!lFp8?TIHN!LXO?gCnsYM-gQxsm=Ek**VmZu7vnuufD7K~GIxfxbsQ@qv2T zPa`tvHB$fFCyZl>3oYg?_wW)C>^_iDOc^B7klnTOoytQH18WkOk)L2BSD0r%xgRSW zQS9elF^?O=_@|58zKLK;(f77l-Zzu}4{fXed2saq!5k#UZAoDBqYQS{sn@j@Vtp|$ zG%gnZ$U|9@u#w1@11Sjl8ze^Co=)7yS(}=;68a3~g;NDe_X^}yJj;~s8xq9ahQ5_r zxAlTMnep*)w1e(TG%tWsjo3RR;yVGPEO4V{Zp?=a_0R#=V^ioQu4YL=BO4r0$$XTX zZfnw#_$V}sDAIDrezGQ+h?q24St0QNug_?{s-pI(^jg`#JRxM1YBV;a@@JQvH8*>> zIJvku74E0NlXkYe_624>znU0J@L<-c=G#F3k4A_)*;ky!C(^uZfj%WB3-*{*B$?9+ zDm$WFp=0(xnt6`vDQV3Jl5f&R(Mp};;q8d3I%Kn>Kx=^;uSVCw0L=gw53%Bp==8Sw zxtx=cs!^-_+i{2OK`Q;913+AXc_&Z5$@z3<)So0CU3;JAv=H?@Zpi~riQ{z-zLtVL z!oF<}@IgJp)Iyz1zVJ42!SPHSkjYNS4%ulVVIXdRuiZ@5Mx8LJS}J#qD^Zi_xQ@>DKDr-_e#>5h3dtje*NcwH_h;i{Sx7}dkdpuW z(yUCjckQsagv*QGMSi9u1`Z|V^}Wjf7B@q%j2DQXyd0nOyqg%m{CK_lAoKlJ7#8M} z%IvR?Vh$6aDWK2W!=i?*<77q&B8O&3?zP(Cs@kapc)&p7En?J;t-TX9abGT#H?TW? ztO5(lPKRuC7fs}zwcUKbRh=7E8wzTsa#Z{a`WR}?UZ%!HohN}d&xJ=JQhpO1PI#>X zHkb>pW04pU%Bj_mf~U}1F1=wxdBZu1790>3Dm44bQ#F=T4V3&HlOLsGH)+AK$cHk6 zia$=$kog?)07HCL*PI6}DRhpM^*%I*kHM<#1Se+AQ!!xyhcy6j7`iDX7Z-2i73_n# zas*?7LkxS-XSqv;YBa zW_n*32D(HTYQ0$feV_Fru1ZxW0g&iwqixPX3=9t4o)o|kOo79V$?$uh?#8Q8e>4e)V6;_(x&ViUVxma+i25qea;d-oK7ouuDsB^ab{ zu1qjQ%`n56VtxBE#0qAzb7lph`Eb-}TYpXB!H-}3Ykqyp`otprp7{VEuW*^IR2n$Fb99*nAtqT&oOFIf z@w*6>YvOGw@Ja?Pp1=whZqydzx@9X4n^2!n83C5{C?G@|E?&$?p*g68)kNvUTJ)I6 z1Q|(#UuP6pj78GUxq11m-GSszc+)X{C2eo-?8ud9sB=3(D47v?`JAa{V(IF zPZQ_0AY*9M97>Jf<o%#O_%Wq}8>YM=q0|tGY+hlXcpE=Z4Od z`NT7Hu2hnvRoqOw@g1f=bv`+nba{GwA$Ak0INlqI1k<9!x_!sL()h?hEWoWrdU3w` zZ%%)VR+Bc@_v!C#koM1p-3v_^L6)_Ktj4HE>aUh%2XZE@JFMOn)J~c`_7VWNb9c-N z2b|SZMR4Z@E7j&q&9(6H3yjEu6HV7{2!1t0lgizD;mZ9$r(r7W5G$ky@w(T_dFnOD z*p#+z$@pKE+>o@%eT(2-p_C}wbQ5s(%Sn_{$HDN@MB+Ev?t@3dPy`%TZ!z}AThZSu zN<1i$siJhXFdjV zP*y|V<`V8t=h#XTRUR~5`c`Z9^-`*BZf?WAehGdg)E2Je)hqFa!k{V(u+(hTf^Yq& zoruUh2(^3pe)2{bvt4&4Y9CY3js)PUHtd4rVG57}uFJL)D(JfSIo^{P=7liFXG zq5yqgof0V8paQcP!gy+;^pp-DA5pj=gbMN0eW=-eY+N8~y+G>t+x}oa!5r>tW$xhI zPQSv=pi;~653Gvf6~*JcQ%t1xOrH2l3Zy@8AoJ+wz@daW@m7?%LXkr!bw9GY@ns3e zSfuWF_gkWnesv?s3I`@}NgE2xwgs&rj?kH-FEy82=O8`+szN ziHch`vvS`zNfap14!&#i9H@wF7}yIPm=UB%(o(}F{wsZ(wA0nJ2aD^@B41>>o-_U6 zUqD~vdo48S8~FTb^+%#zcbQiiYoDKYcj&$#^;Smmb+Ljp(L=1Kt_J!;0s%1|JK}Wi z;={~oL!foo5n8=}rs6MmUW~R&;SIJO3TL4Ky?kh+b2rT9B1Jl4>#Uh-Bec z`Hsp<==#UEW6pGPhNk8H!!DUQR~#F9jEMI6T*OWfN^Ze&X(4nV$wa8QUJ>oTkruH# zm~O<`J7Wxseo@FqaZMl#Y(mrFW9AHM9Kb|XBMqaZ2a)DvJgYipkDD_VUF_PKd~dT7 z#02}bBfPn9a!X!O#83=lbJSK#E}K&yx-HI#T6ua)6o0{|={*HFusCkHzs|Fn&|C3H zBck1cmfcWVUN&i>X$YU^Sn6k2H;r3zuXbJFz)r5~3$d$tUj(l1?o={MM){kjgqXRO zc5R*#{;V7AQh|G|)jLM@wGAK&rm2~@{Pewv#06pHbKn#wL0P6F1!^qw9g&cW3Z=9} zj)POhOlwsh@eF=>z?#sIs*C-Nl(yU!#DaiaxhEs#iJqQ8w%(?+6lU02MYSeDkr!B- zPjMv+on6OLXgGnAtl(ao>|X2Y8*Hb}GRW5}-IzXnoo-d0!m4Vy$GS!XOLy>3_+UGs z2D|YcQx@M#M|}TDOetGi{9lGo9m-=0-^+nKE^*?$^uHkxZh}I{#UTQd;X!L+W@jm( zDg@N4+lUqI92o_rNk{3P>1gxAL=&O;x)ZT=q1mk0kLlE$WeWuY_$0`0jY-Kkt zP*|m3AF}Ubd=`<>(Xg0har*_@x2YH}bn0Wk*OZz3*e5;Zc;2uBdnl8?&XjupbkOeNZsNh6pvsq_ydmJI+*z**{I{0K)-;p1~k8cpJXL$^t!-`E}=*4G^-E8>H!LjTPxSx zcF+cS`ommfKMhNSbas^@YbTpH1*RFrBuATUR zt{oFWSk^$xU&kbFQ;MCX22RAN5F6eq9UfR$ut`Jw--p2YX)A*J69m^!oYfj2y7NYcH6&r+0~_sH^c^nzeN1AU4Ga7=FlR{S|Mm~MpzY0$Z+p2W(a={b-pR9EO1Rs zB%KY|@wLcAA@)KXi!d2_BxrkhDn`DT1=Dec}V!okd{$+wK z4E{n8R*xKyci1(CnNdhf$Dp2(Jpof0-0%-38X=Dd9PQgT+w%Lshx9+loPS~MOm%ZT zt%2B2iL_KU_ita%N>xjB!#71_3=3c}o zgeW~^U_ZTJQ2!PqXulQd=3b=XOQhwATK$y(9$#1jOQ4}4?~l#&nek)H(04f(Sr=s| zWv7Lu1=%WGk4FSw^;;!8&YPM)pQDCY9DhU`hMty1@sq1=Tj7bFsOOBZOFlpR`W>-J$-(kezWJj;`?x-v>ev{*8V z8p|KXJPV$HyQr1A(9LVrM47u-XpcrIyO`yWvx1pVYc&?154aneRpLqgx)EMvRaa#|9?Wwqs2+W8n5~79G z(}iCiLk;?enn}ew`HzhG+tu+Ru@T+K5juvZN)wY;x6HjvqD!&!)$$;1VAh~7fg0K| zEha#aN=Yv|3^~YFH}cc38ovVb%L|g@9W6fo(JtT6$fa?zf@Ct88e}m?i)b*Jgc{fl zExfdvw-BYDmH6>(4QMt#p0;FUIQqkhD}aH?a7)_%JtA~soqj{ppP_82yi9kaxuK>~ ze_)Zt>1?q=ZH*kF{1iq9sr*tVuy=u>Zev}!gEZx@O6-fjyu9X00gpIl-fS_pzjpqJ z1yqBmf9NF!jaF<+YxgH6oXBdK)sH(>VZ)1siyA$P<#KDt;8NT*l_0{xit~5j1P)FN zI8hhYKhQ)i z37^aP13B~u65?sg+_@2Kr^iWHN=U;EDSZ@2W2!5ALhGNWXnFBY%7W?1 z=HI9JzQ-pLKZDYTv<0-lt|6c-RwhxZ)mU2Os{bsX_i^@*fKUj8*aDO5pks=qn3Dv6 zwggpKLuyRCTVPwmw1r}B#AS}?X7b837UlXwp~E2|PJw2SGVueL7){Y&z!jL!XN=0i zU^Eig`S2`{+gU$68aRdWx?BZ{sU_f=8sn~>s~M?GU~`fH5kCc; z8ICp+INM3(3{#k32RZdv6b9MQYdZXNuk7ed8;G?S2nT+NZBG=Tar^KFl2SvhW$bGW#kdWL-I)s_IqVnCDDM9fm8g;P;8 z7t4yZn3^*NQfx7SwmkzP$=fwdC}bafQSEF@pd&P8@H#`swGy_rz;Z?Ty5mkS%>m#% zp_!m9e<()sfKiY(nF<1zBz&&`ZlJf6QLvLhl`_``%RW&{+O>Xhp;lwSsyRqGf=RWd zpftiR`={2(siiPAS|p}@q=NhVc0ELprt%=fMXO3B)4ryC2LT(o=sLM7hJC!}T1@)E zA3^J$3&1*M6Xq>03FX`R&w*NkrZE?FwU+Muut;>qNhj@bX17ZJxnOlPSZ=Zeiz~T_ zOu#yc3t6ONHB;?|r4w+pI)~KGN;HOGC)txxiUN8#mexj+W(cz%9a4sx|IRG=}ia zuEBuba3AHsV2feqw-3MvuL`I+2|`Ud4~7ZkN=JZ;L20|Oxna5vx1qbIh#k2O4$RQF zo`tL()zxaqibg^GbB+BS5#U{@K;WWQj~GcB1zb}zJkPwH|5hZ9iH2308!>_;%msji zJHSL~s)YHBR=Koa1mLEOHos*`gp=s8KA-C zu0aE+W!#iJ*0xqKm3A`fUGy#O+X+5W36myS>Uh2!R*s$aCU^`K&KKLCCDkejX2p=5 z%o7-fl03x`gaSNyr?3_JLv?2RLS3F*8ub>Jd@^Cc17)v8vYEK4aqo?OS@W9mt%ITJ z9=S2%R8M){CugT@k~~0x`}Vl!svYqX=E)c_oU6o}#Hb^%G1l3BudxA{F*tbjG;W_>=xV73pKY53v%>I)@D36I_@&p$h|Aw zonQS`07z_F#@T-%@-Tb|)7;;anoD_WH>9ewFy(ZcEOM$#Y)8>qi7rCnsH9GO-_7zF zu*C87{Df1P4TEOsnzZ@H%&lvV(3V@;Q!%+OYRp`g05PjY^gL$^$-t0Y>H*CDDs?FZly*oZ&dxvsxaUWF!{em4{A>n@vpXg$dwvt@_rgmHF z-MER`ABa8R-t_H*kv>}CzOpz;!>p^^9ztHMsHL|SRnS<-y5Z*r(_}c4=fXF`l^-i}>e7v!qs_jv zqvWhX^F=2sDNWA9c@P0?lUlr6ecrTKM%pNQ^?*Lq?p-0~?_j50xV%^(+H>sMul#Tw zeciF*1=?a7cI(}352%>LO96pD+?9!fNyl^9v3^v&Y4L)mNGK0FN43&Xf8jUlxW1Bw zyiu2;qW-aGNhs=zbuoxnxiwZ3{PFZM#Kw)9H@(hgX23h(`Wm~m4&TvoZoYp{plb^> z_#?vXcxd>r7K+1HKJvhed>gtK`TAbJUazUWQY6T~t2af%#<+Veyr%7-#*A#@&*;@g58{i|E%6yC_InGXCOd{L0;$)z#?n7M`re zh!kO{6=>7I?*}czyF7_frt#)s1CFJ_XE&VrDA?Dp3XbvF{qsEJgb&OLSNz_5g?HpK z9)8rsr4JN!Af3G9!#Qn(6zaUDqLN(g2g8*M)Djap?WMK9NKlkC)E2|-g|#-rp%!Gz zAHd%`iq|81efi93m3yTBw3g0j#;Yb2X{mhRAI?&KDmbGqou(2xiRNb^sV}%%Wu0?< z?($L>(#BO*)^)rSgyNRni$i`R4v;GhlCZ8$@e^ROX(p=2_v6Y!%^As zu022)fHdv_-~Yu_H6WVPLpHQx!W%^6j)cBhS`O3QBW#x(eX54d&I22op(N59b*&$v zFiSRY6rOc^(dgSV1>a7-5C;(5S5MvKcM2Jm-LD9TGqDpP097%52V+0>Xqq!! zq4e3vj53SE6i8J`XcQB|MZPP8j;PAOnpGnllH6#Ku~vS42xP*Nz@~y%db7Xi8s09P z1)e%8ys6&M8D=Dt6&t`iKG_4X=!kgRQoh%Z`dc&mlOUqXk-k`jKv9@(a^2-Upw>?< zt5*^DV~6Zedbec4NVl($2T{&b)zA@b#dUyd>`2JC0=xa_fIm8{5um zr-!ApXZhC8@=vC2WyxO|!@0Km)h8ep*`^he92$@YwP>VcdoS5OC^s38e#7RPsg4j+ zbVGG}WRSET&ZfrcR(x~k8n1rTP%CnfUNKUonD$P?FtNFF#cn!wEIab-;jU=B1dHK@ z(;(yAQJ`O$sMn>h;pf^8{JISW%d+@v6@CnXh9n5TXGC}?FI9i-D0OMaIg&mAg=0Kn zNJ7oz5*ReJukD55fUsMuaP+H4tDN&V9zfqF@ zr=#ecUk9wu{0;!+gl;3Bw=Vn^)z$ahVhhw)io!na&9}LmWurLb0zubxK=UEnU*{5P z+SP}&*(iBKSO4{alBHaY^)5Q=mZ+2OwIooJ7*Q5XJ+2|q`9#f?6myq!&oz?klihLq z4C)$XP!BNS0G_Z1&TM>?Jk{S~{F3n83ioli=IO6f%wkvCl(RFFw~j0tb{GvXTx>*sB0McY0s&SNvj4+^h`9nJ_wM>F!Uc>X}9PifQekn0sKI2SAJP!a4h z5cyGTuCj3ZBM^&{dRelIlT^9zcfaAuL5Y~bl!ppSf`wZbK$z#6U~rdclk``e+!qhe z6Qspo*%<)eu6?C;Bp<^VuW6JI|Ncvyn+LlSl;Mp22Bl7ARQ0Xc24%29(ZrdsIPw&-=yHQ7_Vle|5h>AST0 zUGX2Zk34vp?U~IHT|;$U86T+UUHl_NE4m|}>E~6q``7hccCaT^#y+?wD##Q%HwPd8 zV3x4L4|qqu`B$4(LXqDJngNy-{&@aFBvVsywt@X^}iH7P%>bR?ciC$I^U-4Foa`YKI^qDyGK7k%E%c_P=yzAi`YnxGA%DeNd++j3*h^ z=rn>oBd0|~lZ<6YvmkKY*ZJlJ;Im0tqgWu&E92eqt;+NYdxx`eS(4Hw_Jb5|yVvBg z*tbdY^!AN;luEyN4VRhS@-_DC{({ziH{&Z}iGElSV~qvT>L-8G%+yEL zX#MFOhj{InyKG=mvW-<1B@c-}x$vA(nU?>S>0*eN#!SLzQ)Ex7fvQ)S4D<8|I#N$3 zT5Ei`Z?cxBODHX8(Xp73v`IsAYC@9b;t}z0wxVuQSY1J^GRwDPN@qbM-ZF48T$GZ< z8WU+;Pqo?{ghI-KZ-i*ydXu`Ep0Xw^McH_KE9J0S7G;x8Fe`DVG?j3Pv=0YzJ}yZR z%2=oqHiUjvuk0~Ca>Kol4CFi0_xQT~;_F?=u+!kIDl-9g`#ZNZ9HCy17Ga1v^Jv9# z{T4Kb1-AzUxq*MutfOWWZgD*HnFfyYg0&e9f(5tZ>krPF6{VikNeHoc{linPPt#Si z&*g>(c54V8rT_AX!J&bNm-!umPvOR}vDai#`CX___J#=zeB*{4<&2WpaDncZsOkp* zsg<%@@rbrMkR_ux9?LsQxzoBa1s%$BBn6vk#{&&zUwcfzeCBJUwFYSF$08qDsB;gWQN*g!p8pxjofWbqNSZOEKOaTx@+* zwdt5*Q47@EOZ~EZL9s?1o?A%9TJT=Ob_13yyugvPg*e&ZU(r6^k4=2+D-@n=Hv5vu zSXG|hM(>h9^zn=eQ=$6`JO&70&2|%V5Lsx>)(%#;pcOfu>*nk_3HB_BNaH$`jM<^S zcSftDU1?nL;jy)+sfonQN}(}gUW?d_ikr*3=^{G)=tjBtEPe>TO|0ddVB zTklrSHiW+!#26frPXQQ(YN8DG$PZo?(po(QUCCf_OJC`pw*uey00%gmH!`WJkrKXj2!#6?`T25mTu9OJp2L8z3! z=arrL$ZqxuE{%yV)14Kd>k}j7pxZ6#$Dz8$@WV5p8kTqN<-7W)Q7Gt2{KoOPK_tZ| zf2WG~O5@{qPI+W<4f_;reuFVdO^5`ADC1!JQE|N`s3cq@(0WB!n0uh@*c{=LAd;~} zyGK@hbF-Oo+!nN)@i*O(`@FA#u?o=~e{`4O#5}z&=UkU*50fOrzi11D^&FOqe>wii z?*k+2|EcUs;Gx{!@KBT~>PAwLrIDT7Th=Utu?~?np@t^gFs?zgX=D${RwOY^WGh-+ z+#4$066ISh8eYW#FXWp~S`<*%O^ZuItL1Tyqt8#tZ zY120E;^VG`!lZn&3sPd$RkdHpU#|w+bYV)pJC|SH9g%|5IkxVTQcBA4CL0}$&}ef@ zW^Vtj%M;;_1xxP9x#ex17&4N*{ksO*_4O}xYu(p*JkL#yr}@7b)t5X?%CY<+s5_MJ zuiqt+N_;A(_)%lumoyRFixWa-M7qK_9s6<1X?JDa9fP!+_6u~~M$5L=ipB=7(j#f< zZ34J%=bs549%~_mA(|={uZNs_0?o7;-LBP(ZRnkd{-^|2|=4vUTmtByHL8 zEph`(LSEzQj68a+`d$V<45J7cyv^#|^|%fD#si1Nx!4NW*`l*{->HEWNh6-|g>-=r zXmQ|-i}Ku$ndUeHQ^&ieT!Lf}vf6GaqW9$DJ2NWrqwPY%%4nip$@vK$nRp*_C-v<| zuKz~ZyN&<%!NS26&x?jhy+@awJipMQ-8(X4#Ae5??U<1QMt1l9R=w9fAnEF}NYu$2 z>6}Vkc zIb*A?G*z8^IvibmBKn_u^5&T_1oey0gZS2~obf(#xk=erZGTEdQnt3DMGM+0oPwss zj5zXD;(oWhB_T@~Ig#9@v)AKtXu3>Inmgf@A|-lD-1U>cNyl3h?ADD9)GG4}zUGPk zZzaXe!~Kf?<~@$G?Uql3t8jy9{2!doq4=J}j9ktTxss{p6!9UdjyDERlA*xZ!=Q)KDs5O)phz>Vq3BNGoM(H|=1*Q4$^2fTZw z(%nq1P|5Rt81}SYJpEEzMPl5VJsV5&4e)ZWKDyoZ>1EwpkHx-AQVQc8%JMz;{H~p{=FXV>jIxvm4X*qv52e?Y-f%DJ zxEA165GikEASQ^fH6K#d!Tpu2HP{sFs%E=e$gYd$aj$+xue6N+Wc(rAz~wUsk2`(b z8Kvmyz%bKQxpP}~baG-rwYcYCvkHOi zlkR<=>ZBTU*8RF_d#Bl@zZsRIhx<%~Z@Z=ik z>adw3!DK(8R|q$vy{FTxw%#xliD~6qXmY^7_9kthVPTF~Xy1CfBqbU~?1QmxmU=+k z(ggxvEuA;0e&+ci-zQR{-f7aO{O(Pz_OsEjLh_K>MbvoZ4nxtk5u{g@nPv)cgW_R} z9}EA4K4@z0?7ue}Z(o~R(X&FjejUI2g~08PH1E4w>9o{)S(?1>Z0XMvTb|;&EuyOE zGvWNpYX)Nv<8|a^;1>bh#&znEcl-r!T#pn= z4$?Yudha6F%4b>*8@=BdtXXY4N+`U4Dmx$}>HeVJk-QdTG@t!tVT#0(LeV0gvqyyw z2sEp^9eY0N`u10Tm4n8No&A=)IeEC|gnmEXoNSzu!1<4R<%-9kY_8~5Ej?zRegMn78wuMs#;i&eUA0Zk_RXQ3b&TT} z;SCI=7-FUB@*&;8|n>(_g^HGf3@QODE3LpmX~ELnymQm{Sx9xrKS zK29p~?v@R$0=v6Dr5aW>-!{+h@?Q58|Kz8{{W`%J+lDAdb&M5VHrX_mDY;1-JLnf)ezmPau$)1;=`-FU=-r-83tX=C`S#}GZufju zQ>sXNT0Ny=k@nc%cFnvA_i4SC)?_ORXHq8B4D%el1uPX`c~uG#S1M7C+*MMqLw78E zhY2dI8@+N^qrMI1+;TUda(vGqGSRyU{Fnm`aqrr7bz42c5xsOO-~oZpkzorD1g}Y<6rk&3>PsSGy}W?MtqFky@A(X# zIuNZK0cK?^=;PUAu>j0#HtjbHCV*6?jzA&OoE$*Jlga*}LF`SF?WLhv1O|zqC<>*> zYB;#lsYKx0&kH@BFpW8n*yDcc6?;_zaJs<-jPSkCsSX-!aV=P5kUgF@Nu<{a%#K*F z134Q{9|YX7X(v$62_cY3^G%t~rD>Q0z@)1|zs)vjJ6Jq9;7#Ki`w+eS**En?7;n&7 zu==V3T&eFboN3ZiMx3D8qYc;VjFUk_H-WWCau(VFXSQf~viH0L$gwD$UfFHqNcgN`x}M+YQ6RnN<+@t>JUp#)9YOkqst-Ga?{FsDpEeX0(5v{0J~SEbWiL zXC2}M4?UH@u&|;%0y`eb33ldo4~z-x8zY!oVmV=c+f$m?RfDC35mdQ2E>Pze7KWP- z>!Bh<&57I+O_^s}9Tg^k)h7{xx@0a0IA~GAOt2yy!X%Q$1rt~LbTB6@Du!_0%HV>N zlf)QI1&gvERKwso23mJ!Ou6ZS#zCS5W`gxE5T>C#E|{i<1D35C222I33?Njaz`On7 zi<+VWFP6D{e-{yiN#M|Jgk<44u1TiMI78S5W`Sdb5f+{zu34s{CfWN7a3Cf^@L%!& zN$?|!!9j2c)j$~+R6n#891w-z8(!oBpL2K=+%a$r2|~8-(vQj5_XT`<0Ksf;oP+tz z9CObS!0m)Tgg`K#xBM8B(|Z)Wb&DYL{WTYv`;A=q6~Nnx2+!lTIXtj8J7dZE!P_{z z#f8w6F}^!?^KE#+ZDv+xd5O&3EmomZzsv?>E-~ygGum45fk!SBN&|eo1rKw^?aZJ4 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..28ff446a --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..4f906e0c --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..ac1b06f9 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..9636806f --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "turtle-formatter" diff --git a/src/main/java/de/atextor/turtle/formatter/FMT.java b/src/main/java/de/atextor/turtle/formatter/FMT.java new file mode 100644 index 00000000..61e01777 --- /dev/null +++ b/src/main/java/de/atextor/turtle/formatter/FMT.java @@ -0,0 +1,7 @@ +package de.atextor.turtle.formatter; + +public class FMT { + public static final String FMT = "http://purl.org/atextor/ontology/turtle-formatting"; + + public static final String NS = FMT + "#"; +} diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java new file mode 100644 index 00000000..4aad4a3a --- /dev/null +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -0,0 +1,245 @@ +package de.atextor.turtle.formatter; + +import io.vavr.control.Try; +import lombok.Builder; +import lombok.Value; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.vocabulary.DCTerms; +import org.apache.jena.vocabulary.OWL2; +import org.apache.jena.vocabulary.RDF; +import org.apache.jena.vocabulary.RDFS; +import org.apache.jena.vocabulary.SKOS; +import org.apache.jena.vocabulary.XSD; + +import java.net.URI; +import java.util.List; +import java.util.Set; +import java.util.function.BiFunction; + +@Builder +public class FormattingStyle { + @Builder.Default + Set knownPrefixes = Set.of( + PREFIX_RDF, + PREFIX_RDFS, + PREFIX_XSD, + PREFIX_OWL, + PREFIX_DCTERMS, + PREFIX_FMT + ); + + @Builder.Default + GapStyle afterClosingParenthesis = GapStyle.NEWLINE; + + @Builder.Default + GapStyle afterClosingSquareBracket = GapStyle.SPACE; + + @Builder.Default + GapStyle afterComma = GapStyle.SPACE; + + @Builder.Default + GapStyle afterDot = GapStyle.NEWLINE; + + @Builder.Default + GapStyle afterOpeningParenthesis = GapStyle.SPACE; + + @Builder.Default + GapStyle afterOpeningSquareBracket = GapStyle.NEWLINE; + + @Builder.Default + GapStyle afterSemicolon = GapStyle.NEWLINE; + + @Builder.Default + Alignment alignPrefixes = Alignment.OFF; + + @Builder.Default + GapStyle beforeClosingParenthesis = GapStyle.SPACE; + + @Builder.Default + GapStyle beforeClosingSquareBracket = GapStyle.NEWLINE; + + @Builder.Default + GapStyle beforeComma = GapStyle.NOTHING; + + @Builder.Default + GapStyle beforeDot = GapStyle.SPACE; + + @Builder.Default + GapStyle beforeOpeningParenthesis = GapStyle.SPACE; + + @Builder.Default + GapStyle beforeOpeningSquareBracket = GapStyle.SPACE; + + @Builder.Default + GapStyle beforeSemicolon = GapStyle.SPACE; + + @Builder.Default + Charset charset = Charset.UTF_8; + + @Builder.Default + EndOfLineStyle endOfLine = EndOfLineStyle.LF; + + @Builder.Default + IndentStyle indentStyle = IndentStyle.SPACE; + + @Builder.Default + WrappingStyle wrapListItems = WrappingStyle.FOR_LONG_LINES; + + @Builder.Default + boolean firstPredicateInNewLine = false; + + @Builder.Default + boolean useAForRdfType = true; + + @Builder.Default + boolean useCommaByDefault = false; + + @Builder.Default + Set commaForPredicate = Set.of( RDF.type ); + + @Builder.Default + Set noCommaForPredicate = Set.of(); + + @Builder.Default + boolean useShortLiterals = true; + + @Builder.Default + boolean alignBaseIRI = false; + + @Builder.Default + boolean alignObjects = false; + + @Builder.Default + boolean alignPredicates = false; + + @Builder.Default + int continuationIndentSize = 4; + + @Builder.Default + boolean indentPrediates = true; + + @Builder.Default + boolean insertFinalNewline = true; + + @Builder.Default + int indentSize = 2; + + @Builder.Default + int maxLineLength = 100; + + @Builder.Default + boolean trimTrailingWhitespace = true; + + @Builder.Default + List prefixOrder = List.of( + "rdf", + "rdfs", + "xsd", + "owl" + ); + + @Builder.Default + List subjectOrder = List.of( + OWL2.Ontology, + OWL2.Class, + OWL2.ObjectProperty, + OWL2.DatatypeProperty, + OWL2.AnnotationProperty, + OWL2.NamedIndividual, + OWL2.AllDifferent, + OWL2.Axiom + ); + + @Builder.Default + List predicateOrder = List.of( + RDF.type + ); + + @Builder.Default + List objectOrder = List.of( + OWL2.NamedIndividual, + OWL2.ObjectProperty, + OWL2.DatatypeProperty, + OWL2.AnnotationProperty, + OWL2.FunctionalProperty, + OWL2.InverseFunctionalProperty, + OWL2.TransitiveProperty, + OWL2.SymmetricProperty, + OWL2.AsymmetricProperty, + OWL2.ReflexiveProperty, + OWL2.IrreflexiveProperty + ); + + @Builder.Default + BiFunction anonymousNodeIdGenerator = ( resource, integer ) -> "_:gen" + integer; + + public enum Alignment { + LEFT, + OFF, + RIGHT + } + + public enum Charset { + LATIN1, + UTF_16_BE, + UTF_16_LE, + UTF_8, + UTF_8_BOM + } + + public enum EndOfLineStyle { + CR, + CRLF, + LF + } + + public enum GapStyle { + NEWLINE, + NOTHING, + SPACE + } + + public enum IndentStyle { + SPACE, + TAB + } + + public enum WrappingStyle { + ALWAYS, + FOR_LONG_LINES, + NEVER + } + + @Value + public static class KnownPrefix { + String prefix; + + URI iri; + } + + public static final KnownPrefix PREFIX_FMT = new KnownPrefix( "fmt", URI.create( FMT.NS ) ); + + public static final KnownPrefix PREFIX_RDF = new KnownPrefix( "rdf", URI.create( RDF.uri ) ); + + public static final KnownPrefix PREFIX_RDFS = new KnownPrefix( "rdfs", URI.create( RDFS.uri ) ); + + public static final KnownPrefix PREFIX_XSD = new KnownPrefix( "xsd", URI.create( XSD.NS ) ); + + public static final KnownPrefix PREFIX_OWL = new KnownPrefix( "owl", URI.create( OWL2.NS ) ); + + public static final KnownPrefix PREFIX_DCTERMS = new KnownPrefix( "dcterms", URI.create( DCTerms.NS ) ); + + public static final KnownPrefix PREFIX_VANN = new KnownPrefix( "vann", + URI.create( "http://purl.org/vocab/vann/" ) ); + + public static final KnownPrefix PREFIX_SKOS = new KnownPrefix( "skos", URI.create( SKOS.getURI() ) ); + + public static final KnownPrefix PREFIX_EX = new KnownPrefix( "ex", URI.create( "http://example.org/" ) ); + + public static Try fromModel( final Model model ) { + return null; + } +} diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java new file mode 100644 index 00000000..ef9ecbf6 --- /dev/null +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -0,0 +1,467 @@ +package de.atextor.turtle.formatter; + +import io.vavr.Tuple2; +import io.vavr.collection.HashMap; +import io.vavr.collection.HashSet; +import io.vavr.collection.List; +import io.vavr.collection.Map; +import io.vavr.collection.Set; +import io.vavr.collection.Stream; +import lombok.AllArgsConstructor; +import lombok.Value; +import lombok.With; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFList; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.shared.PrefixMapping; +import org.apache.jena.vocabulary.RDF; +import org.apache.jena.vocabulary.XSD; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Comparator; +import java.util.function.Function; + +public class TurtleFormatter implements Function { + private static final Logger LOG = LoggerFactory.getLogger( TurtleFormatter.class ); + + private final FormattingStyle style; + + private final String beforeDot; + + private final String endOfLine; + + private final Comparator> prefixOrder; + + private final Comparator objectOrder; + + public TurtleFormatter( final FormattingStyle style ) { + this.style = style; + + endOfLine = switch ( style.endOfLine ) { + case CR -> "\r"; + case LF -> "\n"; + case CRLF -> "\r\n"; + }; + + beforeDot = switch ( style.beforeDot ) { + case SPACE -> " "; + case NOTHING -> ""; + case NEWLINE -> endOfLine; + }; + + prefixOrder = Comparator.>comparingInt( entry -> + style.prefixOrder.contains( entry._1() ) ? + style.prefixOrder.indexOf( entry._1() ) : + Integer.MAX_VALUE + ).thenComparing( Tuple2::_1 ); + + objectOrder = Comparator.comparingInt( object -> + style.objectOrder.contains( object ) ? + style.objectOrder.indexOf( object ) : + Integer.MAX_VALUE + ).thenComparing( RDFNode::toString ); + } + + private static List statements( final Model model ) { + return List.ofAll( model.listStatements().toList() ); + } + + private static List statements( final Model model, final Resource subject, final Property predicate, + final RDFNode object ) { + return List.ofAll( model.listStatements( subject, predicate, object ).toList() ); + } + + @Override + public String apply( final Model model ) { + final PrefixMapping prefixMapping = buildPrefixMapping( model ); + + final Comparator predicateOrder = Comparator.comparingInt( property -> + style.predicateOrder.contains( property ) ? + style.predicateOrder.indexOf( property ) : + Integer.MAX_VALUE + ).thenComparing( property -> prefixMapping.shortForm( property.getURI() ) ); + + final State initialState = Stream + .ofAll( anonymousResourcesThatNeedAnId( model ) ) + .zipWithIndex() + .map( entry -> new Tuple2<>( entry._1(), style.anonymousNodeIdGenerator.apply( entry._1(), entry._2() ) ) ) + .foldLeft( new State( model, predicateOrder, prefixMapping ), ( state, entry ) -> + state.withIdentifiedAnonymousResource( entry._1(), entry._2() ) ); + + final State prefixesWritten = writePrefixes( initialState ); + + final Comparator subjectComparator = + Comparator.comparing( statement -> statement.getSubject().isURIResource() ? + prefixMapping.shortForm( statement.getSubject().getURI() ) : statement.getSubject().toString() ); + + final List wellKnownSubjects = List.ofAll( style.subjectOrder ).flatMap( subjectType -> + statements( model, null, RDF.type, subjectType ).sorted( subjectComparator ) ); + final List otherSubjects = statements( model ) + .filter( statement -> !statement.getPredicate().equals( RDF.type ) ) + .sorted( subjectComparator ); + final List statements = wellKnownSubjects.appendAll( otherSubjects ) + .filter( statement -> !( statement.getSubject().isAnon() + && model.contains( null, null, statement.getSubject() ) ) ); + + final State namedResourcesWritten = statements + .map( Statement::getSubject ) + .foldLeft( prefixesWritten, ( state, resource ) -> + resource.isURIResource() ? writeSubject( resource, state.withIndentationLevel( 0 ) ) : + writeAnonymousResource( resource, state.withIndentationLevel( 0 ) ) ); + + final State finalState = List.ofAll( namedResourcesWritten.identifiedAnonymousResources.keySet() ) + .foldLeft( namedResourcesWritten, ( state, resource ) -> + writeSubject( resource, state.withIndentationLevel( 0 ) ) ); + + LOG.debug( "Written {} resources, with {} named anonymous resources", finalState.visitedResources.size(), + finalState.identifiedAnonymousResources.size() ); + + return finalState.print(); + } + + /** + * Anonymous resources that are referred to more than once need to be given an internal id and + * can not be serialized using [ ] notation. + * + * @param model the input model + * @return the set of anonymous resources that are referred to more than once + */ + private Set anonymousResourcesThatNeedAnId( final Model model ) { + return List.ofAll( model::listObjects ) + .filter( RDFNode::isResource ) + .map( RDFNode::asResource ) + .filter( RDFNode::isAnon ) + .filter( object -> statements( model, null, null, object ).toList().size() > 1 ) + .toSet(); + } + + private PrefixMapping buildPrefixMapping( final Model model ) { + final Map prefixMap = Stream.ofAll( style.knownPrefixes ) + .filter( knownPrefix -> model.getNsPrefixURI( knownPrefix.getPrefix() ) == null ) + .toMap( FormattingStyle.KnownPrefix::getPrefix, knownPrefix -> knownPrefix.getIri().toString() ); + return PrefixMapping.Factory.create().setNsPrefixes( model.getNsPrefixMap() ) + .setNsPrefixes( prefixMap.toJavaMap() ); + } + + private State writePrefixes( final State state ) { + final Map prefixes = HashMap.ofAll( state.prefixMapping.getNsPrefixMap() ); + final int maxPrefixLength = prefixes.keySet().map( String::length ).max().getOrElse( 0 ); + final String prefixFormat = switch ( style.alignPrefixes ) { + case OFF -> "@prefix %s: <%s>" + beforeDot + ".%n"; + case LEFT -> "@prefix %-" + maxPrefixLength + "s: <%s>" + beforeDot + ".%n"; + case RIGHT -> "@prefix %" + maxPrefixLength + "s: <%s>" + beforeDot + ".%n"; + }; + + final State prefixesWritten = prefixes.toStream().sorted( prefixOrder ).foldLeft( state, + ( newState, entry ) -> newState.write( String.format( prefixFormat, entry._1(), entry._2() ) ) ); + + return prefixesWritten.newLine(); + } + + private String indent( final int level ) { + final String singleIndent = switch ( style.indentStyle ) { + case SPACE -> " ".repeat( style.indentSize ); + case TAB -> "\\t"; + }; + return singleIndent.repeat( level ); + } + + private String continuationIndent( final int level ) { + final String continuation = switch ( style.indentStyle ) { + case SPACE -> " ".repeat( style.continuationIndentSize ); + case TAB -> "\\t".repeat( 2 ); + }; + return indent( level - 1 ) + continuation; + } + + private State writeDelimiter( final String delimiter, final FormattingStyle.GapStyle before, + final FormattingStyle.GapStyle after, final String indentation, + final State state ) { + final State beforeState = switch ( before ) { + case SPACE -> state.write( " " ); + case NOTHING -> state; + case NEWLINE -> state.newLine().write( indentation ); + }; + + return switch ( after ) { + case SPACE -> beforeState.write( delimiter + " " ); + case NOTHING -> beforeState.write( delimiter ); + case NEWLINE -> beforeState.write( delimiter ).newLine().write( indentation ); + }; + } + + private State writeComma( final State state ) { + return writeDelimiter( ",", style.beforeComma, style.afterComma, + continuationIndent( state.indentationLevel ), state ); + } + + private State writeSemicolon( final State state, final boolean omitLineBreak, + final boolean omitSpaceBeforeSemicolon ) { + final FormattingStyle.GapStyle beforeSemicolon = omitSpaceBeforeSemicolon ? FormattingStyle.GapStyle.NOTHING : + style.beforeSemicolon; + final FormattingStyle.GapStyle afterSemicolon = omitLineBreak ? FormattingStyle.GapStyle.NOTHING : + style.afterSemicolon; + return writeDelimiter( ";", beforeSemicolon, afterSemicolon, + style.alignPredicates ? "" : indent( state.indentationLevel ), state ); + } + + private State writeDot( final State state, final boolean omitSpaceBeforeDot ) { + final FormattingStyle.GapStyle beforeDot = omitSpaceBeforeDot ? FormattingStyle.GapStyle.NOTHING : + style.beforeDot; + return writeDelimiter( ".", beforeDot, style.afterDot, "", state ); + } + + private State writeOpeningSquareBracket( final State state ) { + final FormattingStyle.GapStyle beforeBracket = state.indentationLevel > 0 ? style.beforeOpeningSquareBracket : + FormattingStyle.GapStyle.NOTHING; + return writeDelimiter( "[", beforeBracket, style.afterOpeningSquareBracket, + indent( state.indentationLevel ), state ); + } + + private State writeClosingSquareBracket( final State state ) { + return writeDelimiter( "]", style.beforeClosingSquareBracket, style.afterClosingSquareBracket, + indent( state.indentationLevel ), state ); + } + + private boolean isList( final RDFNode node, final State state ) { + return node.equals( RDF.nil ) || + ( node.isResource() && state.model.contains( node.asResource(), RDF.rest, (RDFNode) null ) ); + } + + private State writeResource( final Resource resource, final State state ) { + if ( isList( resource, state ) ) { + return writeList( resource, state ); + } + if ( resource.isURIResource() ) { + return writeUriResource( resource, state ); + } + return writeAnonymousResource( resource, state ); + } + + private State writeList( final Resource resource, final State state ) { + final State opened = writeDelimiter( "(", style.beforeOpeningParenthesis, style.afterOpeningParenthesis, + continuationIndent( state.indentationLevel ), state ); + final java.util.List elementList = resource.as( RDFList.class ).asJavaList(); + final State elementsWritten = List.ofAll( elementList ).zipWithIndex().foldLeft( opened, ( currentState, indexedElement ) -> { + RDFNode element = indexedElement._1(); + int index = indexedElement._2(); + boolean firstElement = index == 0; + State spaceWritten = firstElement ? currentState : currentState.write( " " ); + return writeRdfNode( element, spaceWritten ); + } ); + + return writeDelimiter( ")", style.beforeClosingParenthesis, style.afterClosingParenthesis, + continuationIndent( state.indentationLevel ), elementsWritten ); + } + + private State writeAnonymousResource( final Resource resource, final State state ) { + if ( state.identifiedAnonymousResources.keySet().contains( resource ) ) { + return state.write( state.identifiedAnonymousResources.getOrElse( resource, "" ) ); + } + + if ( !state.model.contains( resource, null, (RDFNode) null ) ) { + return state.write( "[]" ); + + } + final State afterOpeningSquareBracket = writeOpeningSquareBracket( state ); + final State afterContent = writeSubject( resource, afterOpeningSquareBracket ).removeIndentationLevel(); + return writeClosingSquareBracket( afterContent ); + } + + private State writeUriResource( final Resource resource, final State state ) { + if ( resource.getURI().equals( RDF.type.getURI() ) && style.useAForRdfType ) { + return state.write( "a" ); + } + + return state.write( state.prefixMapping.shortForm( resource.getURI() ) ); + } + + private State writeLiteral( final Literal literal, final State state ) { + if ( literal.getDatatypeURI().equals( XSD.xboolean.getURI() ) ) { + return state.write( literal.getBoolean() ? "true" : "false" ); + } + if ( literal.getDatatypeURI().equals( XSD.xstring.getURI() ) ) { + return state.write( "\"" + literal.getValue().toString() + "\"" ); + } + if ( literal.getDatatypeURI().equals( XSD.decimal.getURI() ) ) { + return state.write( literal.getLexicalForm() ); + } + if ( literal.getDatatypeURI().equals( XSD.integer.getURI() ) ) { + return state.write( literal.getValue().toString() ); + } + if ( literal.getDatatypeURI().equals( XSD.xdouble.getURI() ) ) { + return state.write( "" + literal.getDouble() ); + } + if ( literal.getDatatypeURI().equals( RDF.langString.getURI() ) ) { + return state.write( "\"" + literal.getLexicalForm() + "\"@" + literal.getLanguage() ); + } + + final Resource typeResource = ResourceFactory.createResource( literal.getDatatypeURI() ); + final State literalWritten = state.write( "\"" + literal.getLexicalForm() + "\"^^" ); + return writeUriResource( typeResource, literalWritten ); + } + + private State writeRdfNode( final RDFNode node, final State state ) { + if ( node.isResource() ) { + return writeResource( node.asResource(), state ); + } + + if ( node.isLiteral() ) { + return writeLiteral( node.asLiteral(), state ); + } + + return state; + } + + private State writeProperty( final Property property, final State state ) { + return writeUriResource( property, state ); + } + + private State writeSubject( final Resource resource, final State state ) { + if ( state.visitedResources.contains( resource ) ) { + return state; + } + + // indent + final State indentedSubject = state.write( indent( state.indentationLevel ) ); + // subject + final boolean isIdentifiedAnon = state.identifiedAnonymousResources.keySet().contains( resource ); + final State stateWithSubject = resource.isURIResource() || isIdentifiedAnon ? + writeResource( resource, indentedSubject ).withVisitedResource( resource ) : + indentedSubject.withVisitedResource( resource ); + + final State gapAfterSubject = style.firstPredicateInNewLine || ( resource.isAnon() && !isIdentifiedAnon ) ? + stateWithSubject : stateWithSubject.write( " " ); + + final int predicateAlignment = style.firstPredicateInNewLine ? style.indentSize : gapAfterSubject.alignment; + + // predicates and objects + final Set properties = Stream.ofAll( resource::listProperties ) + .map( Statement::getPredicate ).toSet(); + + return Stream + .ofAll( properties ) + .sorted( state.predicateOrder ) + .zipWithIndex() + .foldLeft( stateWithSubject.addIndentationLevel(), ( currentState, indexedProperty ) -> { + final Property property = indexedProperty._1(); + final int index = indexedProperty._2(); + final boolean firstProperty = index == 0; + final boolean lastProperty = index == properties.size() - 1; + return writeProperty( resource, property, firstProperty, lastProperty, predicateAlignment, + currentState ); + } ); + } + + private State writeProperty( final Resource subject, final Property predicate, final boolean firstProperty, + final boolean lastProperty, final int alignment, final State state ) { + final Set objects = + Stream.ofAll( () -> subject.listProperties( predicate ) ).map( Statement::getObject ).toSet(); + + final boolean useComma = ( style.useCommaByDefault && !style.noCommaForPredicate.contains( predicate ) ) + || ( !style.useCommaByDefault && style.commaForPredicate.contains( predicate ) ); + + final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine ? + state.newLine().write( indent( state.indentationLevel ) ) : state; + + final State predicateAlignment = !firstProperty && style.alignPredicates ? + wrappedPredicate.write( " ".repeat( alignment ) ) : wrappedPredicate; + + final State predicateWrittenOnce = useComma ? + writeProperty( predicate, predicateAlignment ).write( " " ) : predicateAlignment; + + return Stream + .ofAll( objects ) + .sorted( objectOrder ) + .zipWithIndex() + .foldLeft( predicateWrittenOnce, ( currentState, indexedObject ) -> { + final RDFNode object = indexedObject._1(); + final int index = indexedObject._2(); + final boolean lastObject = index == objects.size() - 1; + + final State predicateWritten = useComma ? currentState : + writeProperty( predicate, currentState ); + + final boolean isAnonWithBrackets = object.isAnon() + && !predicateWritten.identifiedAnonymousResources.keySet().contains( object.asResource() ); + final State spaceWritten = ( !isAnonWithBrackets || isList( object, predicateWritten ) ) && !useComma ? + predicateWritten.write( " " ) : + predicateWritten; + + final State objectWritten = writeRdfNode( object, spaceWritten ); + if ( useComma && !lastObject ) { + return writeComma( objectWritten ); + } + + final boolean omitSpaceBeforeDelimiter = object.isResource() && object.isAnon() + && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); + if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 ) { + return writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); + } + return writeSemicolon( objectWritten, lastProperty && lastObject, omitSpaceBeforeDelimiter ); + } ); + } + + @Value + @With + @AllArgsConstructor + private class State { + StringBuffer buffer; + + Model model; + + Set visitedResources; + + Map identifiedAnonymousResources; + + Comparator predicateOrder; + + PrefixMapping prefixMapping; + + int indentationLevel; + + int alignment; + + public State( final Model model, final Comparator predicateOrder, + final PrefixMapping prefixMapping ) { + this( new StringBuffer(), model, HashSet.empty(), HashMap.empty(), predicateOrder, prefixMapping, 0, 0 ); + } + + public State withIdentifiedAnonymousResource( final Resource anonymousResource, final String id ) { + return withIdentifiedAnonymousResources( identifiedAnonymousResources.put( anonymousResource, id ) ); + } + + public State withVisitedResource( final Resource visitedResource ) { + return withVisitedResources( visitedResources.add( visitedResource ) ); + } + + public State addIndentationLevel() { + return withIndentationLevel( indentationLevel + 1 ); + } + + public State removeIndentationLevel() { + return withIndentationLevel( indentationLevel - 1 ); + } + + public State newLine() { + return write( endOfLine ).withAlignment( 0 ); + } + + public State write( final String content ) { + // Interface pretends to use immutable data structures, while the implementation actually reuses the + // same StringBuffer + buffer.append( content ); + return withAlignment( alignment + content.length() ); + } + + public String print() { + return buffer.toString(); + } + } +} diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java new file mode 100644 index 00000000..c892baab --- /dev/null +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -0,0 +1,204 @@ +package de.atextor.turtle.formatter; + +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.ResourceFactory; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TurtleFormatterTest { + @Test + public void testPrefixAlignmentLeft() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .beforeDot( FormattingStyle.GapStyle.SPACE ) + .alignPrefixes( FormattingStyle.Alignment.LEFT ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + @prefix a : . + @prefix abc : . + @prefix abcdef: . + + """; + assertThat( result ).isEqualTo( expected ); + } + + @Test + public void testPrefixAlignmentOff() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .beforeDot( FormattingStyle.GapStyle.SPACE ) + .alignPrefixes( FormattingStyle.Alignment.OFF ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + @prefix a: . + @prefix abc: . + @prefix abcdef: . + + """; + assertThat( result ).isEqualTo( expected ); + } + + @Test + public void testPrefixAlignmentRight() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .beforeDot( FormattingStyle.GapStyle.SPACE ) + .alignPrefixes( FormattingStyle.Alignment.RIGHT ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + @prefix a: . + @prefix abc: . + @prefix abcdef: . + + """; + assertThat( result ).isEqualTo( expected ); + } + + @Test + public void testLiterals() { + final String modelString = """ + @prefix xsd: . + @prefix : . + + :foo1 :bar 1 . + + :foo2 :bar "2" . + + :foo3 :bar true . + + :foo4 :bar -5.0 . + + :foo5 :bar 4.2E9 . + + :foo6 :bar "2021-01-01"^^xsd:date . + + :foo7 :bar "something"^^:custom . + + :foo8 :bar "something"@en . + """; + final Model model = modelFromString( modelString ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testPredicateAlignmentWithFirstPredicateInSameLine() { + final String modelString = """ + @prefix xsd: . + @prefix : . + + :foo1 :bar1 1 ; + :bar2 2 ; + :bar3 3 . + + :something :bar1 1 ; + :bar2 2 ; + :bar3 3 . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .alignPredicates( true ) + .firstPredicateInNewLine( false ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testPredicateAlignmentWithFirstPredicateInNewLine() { + final String modelString = """ + @prefix xsd: . + @prefix : . + + :foo1 + :bar1 1 ; + :bar2 2 ; + :bar3 3 . + + :something + :bar1 1 ; + :bar2 2 ; + :bar3 3 . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testMultipleReferencedAnonNodes() { + // Note how the anonymous node can not be serialized using [ ] because it is referenced multiple times. + final String modelString = """ + @prefix : . + + :a :foo _:gen0 ; + :bar 1 . + + :b :foo _:gen0 . + + _:gen0 :bar 2 . + """; + final Model model = modelFromString( modelString ); + + final String ex = "http://example.com/"; + final Property foo = ResourceFactory.createProperty( ex + "foo" ); + final Property bar = ResourceFactory.createProperty( ex + "bar" ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .predicateOrder( List.of( foo, bar ) ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + private Model modelFromString( final String content ) { + final Model model = ModelFactory.createDefaultModel(); + final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); + model.read( stream, "", "TURTLE" ); + return model; + } + + private Model prefixModel() { + final Model model = ModelFactory.createDefaultModel(); + model.setNsPrefix( "", "http://example.com/" ); + model.setNsPrefix( "a", "http://example.com/a" ); + model.setNsPrefix( "abc", "http://example.com/abc" ); + model.setNsPrefix( "abcdef", "http://example.com/abc" ); + return model; + } +} From 352977ee76d110a5ce47ffd753ef0cf426a9866e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Feb 2021 06:07:49 +0100 Subject: [PATCH 002/280] Add Jacoco and Javadoc config --- build.gradle.kts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 5b5b8e7f..2625ad3f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -59,4 +59,17 @@ tasks { ignoreFailures = false failFast = true } + + javadoc { + (options as CoreJavadocOptions).addStringOption("Xdoclint:accessibility,html,syntax,reference", "-quiet") + options.encoding = "UTF-8" + shouldRunAfter(test) + } + + jacocoTestReport { + reports { + xml.isEnabled = true + xml.destination = file("${buildDir}/reports/jacoco/report.xml") + } + } } From 08a3b46225e7b85a756d84de41d237b95e1ad5e6 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Feb 2021 06:08:00 +0100 Subject: [PATCH 003/280] Update dependency versions --- build.gradle.kts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2625ad3f..4471fabd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,27 +3,26 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask plugins { java jacoco - id("com.github.ben-manes.versions") version "0.33.0" - id("com.adarshr.test-logger") version "2.1.0" + id("com.github.ben-manes.versions") version "0.36.0" + id("com.adarshr.test-logger") version "2.1.1" id("io.franzbecker.gradle-lombok") version "4.0.0" } repositories { - jcenter() - maven(url = "https://jitpack.io") + mavenCentral() } dependencies { - implementation("org.apache.jena:jena:3.16.0") - implementation("org.apache.jena:jena-core:3.16.0") + implementation("org.apache.jena:jena:3.17.0") + implementation("org.apache.jena:jena-core:3.17.0") implementation("io.vavr:vavr:0.10.3") implementation("org.slf4j:slf4j-api:1.7.30") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0") - testImplementation("org.assertj:assertj-core:3.17.2") - testImplementation("net.jqwik:jqwik:1.3.6") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1") + testImplementation("org.assertj:assertj-core:3.19.0") + testImplementation("net.jqwik:jqwik:1.3.10") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1") } jacoco { From 080fa30716ed9f2269b91a9a9d5243b0f2cc7f8d Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 9 Feb 2021 05:23:57 +0100 Subject: [PATCH 004/280] Correctly format lists --- .../turtle/formatter/FormattingStyle.java | 2 +- .../turtle/formatter/TurtleFormatter.java | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index 4aad4a3a..9883de5e 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -32,7 +32,7 @@ public class FormattingStyle { ); @Builder.Default - GapStyle afterClosingParenthesis = GapStyle.NEWLINE; + GapStyle afterClosingParenthesis = GapStyle.NOTHING; @Builder.Default GapStyle afterClosingSquareBracket = GapStyle.SPACE; diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index ef9ecbf6..ce97bdba 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -248,13 +248,14 @@ private State writeList( final Resource resource, final State state ) { final State opened = writeDelimiter( "(", style.beforeOpeningParenthesis, style.afterOpeningParenthesis, continuationIndent( state.indentationLevel ), state ); final java.util.List elementList = resource.as( RDFList.class ).asJavaList(); - final State elementsWritten = List.ofAll( elementList ).zipWithIndex().foldLeft( opened, ( currentState, indexedElement ) -> { - RDFNode element = indexedElement._1(); - int index = indexedElement._2(); - boolean firstElement = index == 0; - State spaceWritten = firstElement ? currentState : currentState.write( " " ); - return writeRdfNode( element, spaceWritten ); - } ); + final State elementsWritten = List.ofAll( elementList ).zipWithIndex() + .foldLeft( opened, ( currentState, indexedElement ) -> { + RDFNode element = indexedElement._1(); + int index = indexedElement._2(); + boolean firstElement = index == 0; + State spaceWritten = firstElement ? currentState : currentState.write( " " ); + return writeRdfNode( element, spaceWritten ); + } ); return writeDelimiter( ")", style.beforeClosingParenthesis, style.afterClosingParenthesis, continuationIndent( state.indentationLevel ), elementsWritten ); @@ -390,7 +391,7 @@ private State writeProperty( final Resource subject, final Property predicate, f final boolean isAnonWithBrackets = object.isAnon() && !predicateWritten.identifiedAnonymousResources.keySet().contains( object.asResource() ); - final State spaceWritten = ( !isAnonWithBrackets || isList( object, predicateWritten ) ) && !useComma ? + final State spaceWritten = !isAnonWithBrackets && !isList( object, predicateWritten ) && !useComma ? predicateWritten.write( " " ) : predicateWritten; @@ -399,7 +400,9 @@ private State writeProperty( final Resource subject, final Property predicate, f return writeComma( objectWritten ); } - final boolean omitSpaceBeforeDelimiter = object.isResource() && object.isAnon() + final boolean omitSpaceBeforeDelimiter = object.isResource() + && object.isAnon() + && !( isList( object, objectWritten ) && style.afterClosingParenthesis == FormattingStyle.GapStyle.NOTHING ) && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 ) { return writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); From c1df4b4ccc3964cdecd790b124467f5325dce25a Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 11 Feb 2021 07:09:08 +0100 Subject: [PATCH 005/280] Correctly write long form URIs --- .../java/de/atextor/turtle/formatter/TurtleFormatter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index ce97bdba..7cfde65e 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -280,7 +280,9 @@ private State writeUriResource( final Resource resource, final State state ) { return state.write( "a" ); } - return state.write( state.prefixMapping.shortForm( resource.getURI() ) ); + final String uri = resource.getURI(); + final String shortForm = state.prefixMapping.shortForm( uri ); + return state.write( shortForm.equals( uri ) ? "<" + uri + ">" : shortForm ); } private State writeLiteral( final Literal literal, final State state ) { From cbce231d00f90400a0ca4bb832f571a2824e7185 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 12 Feb 2021 07:13:17 +0100 Subject: [PATCH 006/280] Improve rendering of anonymous node --- .../turtle/formatter/TurtleFormatter.java | 77 +++++++++++++------ 1 file changed, 52 insertions(+), 25 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 7cfde65e..53e8e289 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -111,13 +111,26 @@ public String apply( final Model model ) { final State namedResourcesWritten = statements .map( Statement::getSubject ) - .foldLeft( prefixesWritten, ( state, resource ) -> - resource.isURIResource() ? writeSubject( resource, state.withIndentationLevel( 0 ) ) : - writeAnonymousResource( resource, state.withIndentationLevel( 0 ) ) ); + .foldLeft( prefixesWritten, ( state, resource ) -> { + if ( !resource.listProperties().hasNext() || state.visitedResources.contains( resource ) ) { + return state; + } + if ( resource.isURIResource() ) { + return writeSubject( resource, state.withIndentationLevel( 0 ) ); + } + final State resourceWritten = writeAnonymousResource( resource, state.withIndentationLevel( 0 ) ); + final boolean omitSpaceBeforeDelimiter = !state.identifiedAnonymousResources.keySet() + .contains( resource ); + return writeDot( resourceWritten, omitSpaceBeforeDelimiter ).newLine(); + } ); final State finalState = List.ofAll( namedResourcesWritten.identifiedAnonymousResources.keySet() ) - .foldLeft( namedResourcesWritten, ( state, resource ) -> - writeSubject( resource, state.withIndentationLevel( 0 ) ) ); + .foldLeft( namedResourcesWritten, ( state, resource ) -> { + if ( !resource.listProperties().hasNext() ) { + return state; + } + return writeSubject( resource, state.withIndentationLevel( 0 ) ); + } ); LOG.debug( "Written {} resources, with {} named anonymous resources", finalState.visitedResources.size(), finalState.identifiedAnonymousResources.size() ); @@ -202,13 +215,12 @@ private State writeComma( final State state ) { } private State writeSemicolon( final State state, final boolean omitLineBreak, - final boolean omitSpaceBeforeSemicolon ) { + final boolean omitSpaceBeforeSemicolon, final String nextLineIndentation ) { final FormattingStyle.GapStyle beforeSemicolon = omitSpaceBeforeSemicolon ? FormattingStyle.GapStyle.NOTHING : style.beforeSemicolon; final FormattingStyle.GapStyle afterSemicolon = omitLineBreak ? FormattingStyle.GapStyle.NOTHING : style.afterSemicolon; - return writeDelimiter( ";", beforeSemicolon, afterSemicolon, - style.alignPredicates ? "" : indent( state.indentationLevel ), state ); + return writeDelimiter( ";", beforeSemicolon, afterSemicolon, nextLineIndentation, state ); } private State writeDot( final State state, final boolean omitSpaceBeforeDot ) { @@ -250,10 +262,10 @@ private State writeList( final Resource resource, final State state ) { final java.util.List elementList = resource.as( RDFList.class ).asJavaList(); final State elementsWritten = List.ofAll( elementList ).zipWithIndex() .foldLeft( opened, ( currentState, indexedElement ) -> { - RDFNode element = indexedElement._1(); - int index = indexedElement._2(); - boolean firstElement = index == 0; - State spaceWritten = firstElement ? currentState : currentState.write( " " ); + final RDFNode element = indexedElement._1(); + final int index = indexedElement._2(); + final boolean firstElement = index == 0; + final State spaceWritten = firstElement ? currentState : currentState.write( " " ); return writeRdfNode( element, spaceWritten ); } ); @@ -267,12 +279,15 @@ private State writeAnonymousResource( final Resource resource, final State state } if ( !state.model.contains( resource, null, (RDFNode) null ) ) { - return state.write( "[]" ); + return state.write( " []" ); } + if ( state.visitedResources.contains( resource ) ) { + return state; + } final State afterOpeningSquareBracket = writeOpeningSquareBracket( state ); - final State afterContent = writeSubject( resource, afterOpeningSquareBracket ).removeIndentationLevel(); - return writeClosingSquareBracket( afterContent ); + final State afterContent = writeSubject( resource, afterOpeningSquareBracket ); + return writeClosingSquareBracket( afterContent ).withVisitedResource( resource ); } private State writeUriResource( final Resource resource, final State state ) { @@ -370,11 +385,15 @@ private State writeProperty( final Resource subject, final Property predicate, f final boolean useComma = ( style.useCommaByDefault && !style.noCommaForPredicate.contains( predicate ) ) || ( !style.useCommaByDefault && style.commaForPredicate.contains( predicate ) ); - final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine ? - state.newLine().write( indent( state.indentationLevel ) ) : state; + final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine ? state.newLine() : state; + + final State indentedPredicate = + firstProperty && ( style.firstPredicateInNewLine || ( subject + .isAnon() && !state.identifiedAnonymousResources.keySet().contains( subject ) ) ) ? + wrappedPredicate.write( indent( state.indentationLevel ) ) : wrappedPredicate; final State predicateAlignment = !firstProperty && style.alignPredicates ? - wrappedPredicate.write( " ".repeat( alignment ) ) : wrappedPredicate; + indentedPredicate.write( " ".repeat( alignment ) ) : indentedPredicate; final State predicateWrittenOnce = useComma ? writeProperty( predicate, predicateAlignment ).write( " " ) : predicateAlignment; @@ -393,7 +412,8 @@ private State writeProperty( final Resource subject, final Property predicate, f final boolean isAnonWithBrackets = object.isAnon() && !predicateWritten.identifiedAnonymousResources.keySet().contains( object.asResource() ); - final State spaceWritten = !isAnonWithBrackets && !isList( object, predicateWritten ) && !useComma ? + final boolean isList = isList( object, predicateWritten ); + final State spaceWritten = !isAnonWithBrackets && !isList && !useComma ? predicateWritten.write( " " ) : predicateWritten; @@ -402,14 +422,21 @@ private State writeProperty( final Resource subject, final Property predicate, f return writeComma( objectWritten ); } - final boolean omitSpaceBeforeDelimiter = object.isResource() - && object.isAnon() - && !( isList( object, objectWritten ) && style.afterClosingParenthesis == FormattingStyle.GapStyle.NOTHING ) - && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); - if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 ) { + final boolean listWritten = isList && style.afterClosingParenthesis == FormattingStyle.GapStyle.NOTHING; + final boolean omitSpaceBeforeDelimiter = + object.isResource() + && object.isAnon() + && !listWritten + && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); + if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && + ( currentState.identifiedAnonymousResources.keySet().contains( subject ) || !subject.isAnon() ) ) { return writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); } - return writeSemicolon( objectWritten, lastProperty && lastObject, omitSpaceBeforeDelimiter ); + final String nextLineIndentation = style.alignPredicates || ( subject.isAnon() && lastProperty ) ? "" : + indent( objectWritten.indentationLevel ); + final State semicolonWritten = writeSemicolon( objectWritten, lastProperty && lastObject, + omitSpaceBeforeDelimiter, nextLineIndentation ); + return subject.isAnon() && lastProperty ? semicolonWritten.removeIndentationLevel() : semicolonWritten; } ); } From 2f5e9537c6398c89d4567ed141a68bdf489bb876 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 16 Feb 2021 06:11:19 +0100 Subject: [PATCH 007/280] Use proper double serialization --- .../turtle/formatter/FormattingStyle.java | 53 +++++++++++-------- .../turtle/formatter/TurtleFormatter.java | 2 +- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index 9883de5e..0cae4131 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -15,12 +15,35 @@ import org.apache.jena.vocabulary.XSD; import java.net.URI; +import java.text.DecimalFormat; +import java.text.NumberFormat; import java.util.List; import java.util.Set; import java.util.function.BiFunction; @Builder public class FormattingStyle { + public static final KnownPrefix PREFIX_FMT = new KnownPrefix( "fmt", URI.create( FMT.NS ) ); + + public static final KnownPrefix PREFIX_RDF = new KnownPrefix( "rdf", URI.create( RDF.uri ) ); + + public static final KnownPrefix PREFIX_RDFS = new KnownPrefix( "rdfs", URI.create( RDFS.uri ) ); + + public static final KnownPrefix PREFIX_XSD = new KnownPrefix( "xsd", URI.create( XSD.NS ) ); + + public static final KnownPrefix PREFIX_OWL = new KnownPrefix( "owl", URI.create( OWL2.NS ) ); + + public static final KnownPrefix PREFIX_DCTERMS = new KnownPrefix( "dcterms", URI.create( DCTerms.NS ) ); + + public static final FormattingStyle DEFAULT = builder().build(); + + public static final KnownPrefix PREFIX_VANN = new KnownPrefix( "vann", + URI.create( "http://purl.org/vocab/vann/" ) ); + + public static final KnownPrefix PREFIX_SKOS = new KnownPrefix( "skos", URI.create( SKOS.getURI() ) ); + + public static final KnownPrefix PREFIX_EX = new KnownPrefix( "ex", URI.create( "http://example.org/" ) ); + @Builder.Default Set knownPrefixes = Set.of( PREFIX_RDF, @@ -79,6 +102,9 @@ public class FormattingStyle { @Builder.Default Charset charset = Charset.UTF_8; + @Builder.Default + NumberFormat doubleFormat = new DecimalFormat( "0.####E0" ); + @Builder.Default EndOfLineStyle endOfLine = EndOfLineStyle.LF; @@ -176,6 +202,10 @@ public class FormattingStyle { @Builder.Default BiFunction anonymousNodeIdGenerator = ( resource, integer ) -> "_:gen" + integer; + public static Try fromModel( final Model model ) { + return null; + } + public enum Alignment { LEFT, OFF, @@ -219,27 +249,4 @@ public static class KnownPrefix { URI iri; } - - public static final KnownPrefix PREFIX_FMT = new KnownPrefix( "fmt", URI.create( FMT.NS ) ); - - public static final KnownPrefix PREFIX_RDF = new KnownPrefix( "rdf", URI.create( RDF.uri ) ); - - public static final KnownPrefix PREFIX_RDFS = new KnownPrefix( "rdfs", URI.create( RDFS.uri ) ); - - public static final KnownPrefix PREFIX_XSD = new KnownPrefix( "xsd", URI.create( XSD.NS ) ); - - public static final KnownPrefix PREFIX_OWL = new KnownPrefix( "owl", URI.create( OWL2.NS ) ); - - public static final KnownPrefix PREFIX_DCTERMS = new KnownPrefix( "dcterms", URI.create( DCTerms.NS ) ); - - public static final KnownPrefix PREFIX_VANN = new KnownPrefix( "vann", - URI.create( "http://purl.org/vocab/vann/" ) ); - - public static final KnownPrefix PREFIX_SKOS = new KnownPrefix( "skos", URI.create( SKOS.getURI() ) ); - - public static final KnownPrefix PREFIX_EX = new KnownPrefix( "ex", URI.create( "http://example.org/" ) ); - - public static Try fromModel( final Model model ) { - return null; - } } diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 53e8e289..e4481953 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -314,7 +314,7 @@ private State writeLiteral( final Literal literal, final State state ) { return state.write( literal.getValue().toString() ); } if ( literal.getDatatypeURI().equals( XSD.xdouble.getURI() ) ) { - return state.write( "" + literal.getDouble() ); + return state.write( style.doubleFormat.format( literal.getDouble() ) ); } if ( literal.getDatatypeURI().equals( RDF.langString.getURI() ) ) { return state.write( "\"" + literal.getLexicalForm() + "\"@" + literal.getLanguage() ); From 639b012247ce57694d940c5c67c0edce11b1ea76 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 16 Feb 2021 06:11:55 +0100 Subject: [PATCH 008/280] Add test for top level anonymous nodes --- .../turtle/formatter/TurtleFormatterTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index c892baab..b6cecf84 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -186,6 +186,32 @@ public void testMultipleReferencedAnonNodes() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testTopLevelAnonymousNode() { + final String modelString = """ + @prefix : . + + [ + :foo 1 ; + :bar 2 ; + :baz 3 ; + ] . + """; + final Model model = modelFromString( modelString ); + + final String ex = "http://example.com/"; + final Property foo = ResourceFactory.createProperty( ex + "foo" ); + final Property bar = ResourceFactory.createProperty( ex + "bar" ); + final Property baz = ResourceFactory.createProperty( ex + "baz" ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .predicateOrder( List.of( foo, bar, baz ) ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); From 1d5a41de403b65ef7320ce1b1c8100f0c299a7fb Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 16 Feb 2021 06:13:34 +0100 Subject: [PATCH 009/280] Add Property-based test --- .../TurtleFormatterPropertyTest.java | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java new file mode 100644 index 00000000..2b1cc30f --- /dev/null +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -0,0 +1,174 @@ +package de.atextor.turtle.formatter; + +import net.jqwik.api.Arbitraries; +import net.jqwik.api.Arbitrary; +import net.jqwik.api.Combinators; +import net.jqwik.api.ForAll; +import net.jqwik.api.Property; +import net.jqwik.api.Provide; +import org.apache.jena.datatypes.xsd.XSDDatatype; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.riot.RDFLanguages; + +import java.io.StringReader; +import java.util.List; +import java.util.function.Supplier; + +import static org.junit.jupiter.api.Assertions.fail; + +public class TurtleFormatterPropertyTest { + private final TurtleFormatter formatter = new TurtleFormatter( FormattingStyle.builder().build() ); + + @Provide + Arbitrary anyString() { + return Arbitraries.strings().ofMaxLength( 10 ); + } + + @Provide + Arbitrary anyStringLiteral() { + return anyString().map( ResourceFactory::createStringLiteral ); + } + + @Provide + Arbitrary anyLanguageCode() { + return Arbitraries.of( "en", "de" ); + } + + @Provide + Arbitrary anyLangStringLiteral() { + return Combinators.combine( anyString(), anyLanguageCode() ).as( ResourceFactory::createLangLiteral ); + } + + @Provide + Arbitrary anyFloatLiteral() { + return Arbitraries.floats() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDfloat ) ); + } + + @Provide + Arbitrary anyDoubleLiteral() { + return Arbitraries.doubles() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDdouble ) ); + } + + @Provide + Arbitrary anyIntLiteral() { + return Arbitraries.integers() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDint ) ); + } + + @Provide + Arbitrary anyLongLiteral() { + return Arbitraries.longs() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDlong ) ); + } + + @Provide + Arbitrary anyShortLiteral() { + return Arbitraries.shorts() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDshort ) ); + } + + @Provide + Arbitrary anyByteLiteral() { + return Arbitraries.bytes() + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDbyte ) ); + } + + @Provide + Arbitrary anyUnsignedByteLiteral() { + return Arbitraries.integers().between( 0, 255 ) + .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDunsignedByte ) ); + } + + @Provide + Arbitrary anyLiteral() { + return Arbitraries + .oneOf( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), anyDoubleLiteral(), + anyIntLiteral(), anyLongLiteral(), anyShortLiteral(), anyByteLiteral(), anyUnsignedByteLiteral() ); + } + + @Provide + Arbitrary anyAnonymousResource() { + return Arbitraries.of( ResourceFactory.createResource() ); + } + + @Provide + Arbitrary anyUrl() { + return Arbitraries.integers().between( 0, 100 ).map( number -> "http://example.com/" + number ); + } + + @Provide + Arbitrary anyUrn() { + return Arbitraries.integers().map( number -> "urn:ex:" + number ); + } + + @Provide + Arbitrary anyUri() { + return Arbitraries.oneOf( anyUrl(), anyUrn() ); + } + + @Provide + Arbitrary anyNamedResource() { + return anyUri().map( ResourceFactory::createResource ); + } + + @Provide + Arbitrary anyResource() { + return Arbitraries.oneOf( anyAnonymousResource(), anyNamedResource() ); + } + + @Provide + Arbitrary anyProperty() { + return anyUri().map( ResourceFactory::createProperty ); + } + + @Provide + Arbitrary anyStatement( final Model model ) { + return Combinators.combine( anyResource(), anyProperty(), anyRdfNode( model ) ) + .as( ResourceFactory::createStatement ); + } + + @Provide + Arbitrary anyList( final Model model ) { + final Supplier> elements = () -> anyRdfNode( model ); + return Arbitraries.lazyOf( elements, elements ).list().ofMaxSize( 10 ) + .map( list -> model.createList( list.iterator() ) ); + } + + @Provide + Arbitrary anyRdfNode( final Model model ) { + return Arbitraries.oneOf( anyLiteral(), anyResource(), anyList( model ) ); + } + + @Provide + Arbitrary> anyListOfStatements( final Model model ) { + return anyStatement( model ).list().ofMaxSize( 5 ); + } + + @Provide + Arbitrary anyModel() { + final Model model = ModelFactory.createDefaultModel(); + return anyListOfStatements( model ).map( statements -> { + model.add( statements ); + return model; + } ); + } + + @Property + public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) final Model model ) { + final String result = formatter.apply( model ); + final Model newModel = ModelFactory.createDefaultModel(); + try { + newModel.read( new StringReader( result ), "", RDFLanguages.strLangTurtle ); + } catch ( final RuntimeException e ) { + fail(); + } + } +} From 1055e959a178b98e8d6feea66f31a3baeaa45761 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 16 Feb 2021 06:15:07 +0100 Subject: [PATCH 010/280] Simplify jena dependencies --- build.gradle.kts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4471fabd..6af1194f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,8 +13,7 @@ repositories { } dependencies { - implementation("org.apache.jena:jena:3.17.0") - implementation("org.apache.jena:jena-core:3.17.0") + implementation("org.apache.jena:apache-jena-libs:3.17.0") implementation("io.vavr:vavr:0.10.3") implementation("org.slf4j:slf4j-api:1.7.30") @@ -60,15 +59,15 @@ tasks { } javadoc { - (options as CoreJavadocOptions).addStringOption("Xdoclint:accessibility,html,syntax,reference", "-quiet") - options.encoding = "UTF-8" - shouldRunAfter(test) - } + (options as CoreJavadocOptions).addStringOption("Xdoclint:accessibility,html,syntax,reference", "-quiet") + options.encoding = "UTF-8" + shouldRunAfter(test) + } jacocoTestReport { - reports { - xml.isEnabled = true - xml.destination = file("${buildDir}/reports/jacoco/report.xml") - } - } + reports { + xml.isEnabled = true + xml.destination = file("${buildDir}/reports/jacoco/report.xml") + } + } } From b9e3009d202742082529a330b4e978fc8024899e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 16 Feb 2021 07:10:46 +0100 Subject: [PATCH 011/280] Fix indendation of predicates in non-top-level anon nodes --- .../de/atextor/turtle/formatter/TurtleFormatter.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index e4481953..1fe271d0 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -387,10 +387,12 @@ private State writeProperty( final Resource subject, final Property predicate, f final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine ? state.newLine() : state; - final State indentedPredicate = - firstProperty && ( style.firstPredicateInNewLine || ( subject - .isAnon() && !state.identifiedAnonymousResources.keySet().contains( subject ) ) ) ? - wrappedPredicate.write( indent( state.indentationLevel ) ) : wrappedPredicate; + final State indentedPredicate = firstProperty && ( + style.firstPredicateInNewLine || ( + subject.isAnon() && + !state.identifiedAnonymousResources.keySet().contains( subject ) + && state.indentationLevel <= 1 ) ) ? + wrappedPredicate.write( indent( state.indentationLevel ) ) : wrappedPredicate; final State predicateAlignment = !firstProperty && style.alignPredicates ? indentedPredicate.write( " ".repeat( alignment ) ) : indentedPredicate; From c28d65d3b26dc5d7bda1a4f2cfa4ce8fa987c736 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 17 Feb 2021 05:56:25 +0100 Subject: [PATCH 012/280] Evaluate insertFinalNewLine --- .../java/de/atextor/turtle/formatter/TurtleFormatter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 1fe271d0..e200b614 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -124,7 +124,7 @@ public String apply( final Model model ) { return writeDot( resourceWritten, omitSpaceBeforeDelimiter ).newLine(); } ); - final State finalState = List.ofAll( namedResourcesWritten.identifiedAnonymousResources.keySet() ) + final State allResourcesWritten = List.ofAll( namedResourcesWritten.identifiedAnonymousResources.keySet() ) .foldLeft( namedResourcesWritten, ( state, resource ) -> { if ( !resource.listProperties().hasNext() ) { return state; @@ -132,6 +132,8 @@ public String apply( final Model model ) { return writeSubject( resource, state.withIndentationLevel( 0 ) ); } ); + final State finalState = style.insertFinalNewline ? allResourcesWritten.newLine() : allResourcesWritten; + LOG.debug( "Written {} resources, with {} named anonymous resources", finalState.visitedResources.size(), finalState.identifiedAnonymousResources.size() ); From 98669f69f685d1b016264889af4a27b2274bcf51 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 17 Feb 2021 06:23:02 +0100 Subject: [PATCH 013/280] Support alignment of objects --- .../turtle/formatter/TurtleFormatter.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index e200b614..1a397173 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -292,14 +292,18 @@ private State writeAnonymousResource( final Resource resource, final State state return writeClosingSquareBracket( afterContent ).withVisitedResource( resource ); } - private State writeUriResource( final Resource resource, final State state ) { + private String uriResource( final Resource resource, final State state ) { if ( resource.getURI().equals( RDF.type.getURI() ) && style.useAForRdfType ) { - return state.write( "a" ); + return "a"; } final String uri = resource.getURI(); final String shortForm = state.prefixMapping.shortForm( uri ); - return state.write( shortForm.equals( uri ) ? "<" + uri + ">" : shortForm ); + return shortForm.equals( uri ) ? "<" + uri + ">" : shortForm; + } + + private State writeUriResource( final Resource resource, final State state ) { + return state.write( uriResource( resource, state ) ); } private State writeLiteral( final Literal literal, final State state ) { @@ -365,6 +369,9 @@ private State writeSubject( final Resource resource, final State state ) { final Set properties = Stream.ofAll( resource::listProperties ) .map( Statement::getPredicate ).toSet(); + final int maxPropertyWidth = properties.map( property -> + uriResource( property, state ) ).map( String::length ).max().getOrElse( 0 ); + return Stream .ofAll( properties ) .sorted( state.predicateOrder ) @@ -374,13 +381,17 @@ private State writeSubject( final Resource resource, final State state ) { final int index = indexedProperty._2(); final boolean firstProperty = index == 0; final boolean lastProperty = index == properties.size() - 1; + final int propertyWidth = uriResource( property, currentState ).length(); + final String gapAfterPredicate = style.alignObjects ? + " ".repeat( maxPropertyWidth - propertyWidth + 1 ) : " "; return writeProperty( resource, property, firstProperty, lastProperty, predicateAlignment, - currentState ); + gapAfterPredicate, currentState ); } ); } private State writeProperty( final Resource subject, final Property predicate, final boolean firstProperty, - final boolean lastProperty, final int alignment, final State state ) { + final boolean lastProperty, final int alignment, + final String gapAfterPredicate, final State state ) { final Set objects = Stream.ofAll( () -> subject.listProperties( predicate ) ).map( Statement::getObject ).toSet(); @@ -399,8 +410,8 @@ private State writeProperty( final Resource subject, final Property predicate, f final State predicateAlignment = !firstProperty && style.alignPredicates ? indentedPredicate.write( " ".repeat( alignment ) ) : indentedPredicate; - final State predicateWrittenOnce = useComma ? - writeProperty( predicate, predicateAlignment ).write( " " ) : predicateAlignment; + final State predicateWrittenOnce = useComma ? writeProperty( predicate, predicateAlignment ) + .write( gapAfterPredicate ) : predicateAlignment; return Stream .ofAll( objects ) @@ -418,7 +429,7 @@ private State writeProperty( final Resource subject, final Property predicate, f && !predicateWritten.identifiedAnonymousResources.keySet().contains( object.asResource() ); final boolean isList = isList( object, predicateWritten ); final State spaceWritten = !isAnonWithBrackets && !isList && !useComma ? - predicateWritten.write( " " ) : + predicateWritten.write( gapAfterPredicate ) : predicateWritten; final State objectWritten = writeRdfNode( object, spaceWritten ); From 851d3e0c1ae473cf0111ba611d299a8faff18219 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 18 Feb 2021 05:46:50 +0100 Subject: [PATCH 014/280] Support predicate alignment and object alignment --- .../turtle/formatter/TurtleFormatter.java | 27 +++++----- .../turtle/formatter/TurtleFormatterTest.java | 50 +++++++++++++++++++ 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 1a397173..e93c8f9f 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -376,7 +376,7 @@ private State writeSubject( final Resource resource, final State state ) { .ofAll( properties ) .sorted( state.predicateOrder ) .zipWithIndex() - .foldLeft( stateWithSubject.addIndentationLevel(), ( currentState, indexedProperty ) -> { + .foldLeft( gapAfterSubject.addIndentationLevel(), ( currentState, indexedProperty ) -> { final Property property = indexedProperty._1(); final int index = indexedProperty._2(); final boolean firstProperty = index == 0; @@ -398,16 +398,18 @@ private State writeProperty( final Resource subject, final Property predicate, f final boolean useComma = ( style.useCommaByDefault && !style.noCommaForPredicate.contains( predicate ) ) || ( !style.useCommaByDefault && style.commaForPredicate.contains( predicate ) ); - final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine ? state.newLine() : state; + final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine && !subject.isAnon() ? + state.newLine() : state; - final State indentedPredicate = firstProperty && ( - style.firstPredicateInNewLine || ( - subject.isAnon() && - !state.identifiedAnonymousResources.keySet().contains( subject ) - && state.indentationLevel <= 1 ) ) ? + final boolean inBrackets = subject.isAnon() && !state.identifiedAnonymousResources.keySet().contains( subject ); + + final boolean shouldIndentFirstProperty = firstProperty && ( + ( style.firstPredicateInNewLine && !inBrackets ) || ( inBrackets && state.indentationLevel <= 1 ) ); + final boolean shouldIndentOtherProperty = !firstProperty && inBrackets; + final State indentedPredicate = shouldIndentFirstProperty || shouldIndentOtherProperty ? wrappedPredicate.write( indent( state.indentationLevel ) ) : wrappedPredicate; - final State predicateAlignment = !firstProperty && style.alignPredicates ? + final State predicateAlignment = !firstProperty && style.alignPredicates && !subject.isAnon() ? indentedPredicate.write( " ".repeat( alignment ) ) : indentedPredicate; final State predicateWrittenOnce = useComma ? writeProperty( predicate, predicateAlignment ) @@ -443,12 +445,13 @@ private State writeProperty( final Resource subject, final Property predicate, f && object.isAnon() && !listWritten && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); - if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && - ( currentState.identifiedAnonymousResources.keySet().contains( subject ) || !subject.isAnon() ) ) { + if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && !inBrackets ) { return writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); } - final String nextLineIndentation = style.alignPredicates || ( subject.isAnon() && lastProperty ) ? "" : - indent( objectWritten.indentationLevel ); + final String nextLineIndentation = + ( style.alignPredicates || ( subject.isAnon() ) ) + && !( !subject.isAnon() && !lastObject ) ? "" : + indent( objectWritten.indentationLevel ); final State semicolonWritten = writeSemicolon( objectWritten, lastProperty && lastObject, omitSpaceBeforeDelimiter, nextLineIndentation ); return subject.isAnon() && lastProperty ? semicolonWritten.removeIndentationLevel() : semicolonWritten; diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index b6cecf84..79f3db0d 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -22,6 +22,7 @@ public void testPrefixAlignmentLeft() { .knownPrefixes( Set.of() ) .beforeDot( FormattingStyle.GapStyle.SPACE ) .alignPrefixes( FormattingStyle.Alignment.LEFT ) + .insertFinalNewline( false ) .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); @@ -42,6 +43,7 @@ public void testPrefixAlignmentOff() { .knownPrefixes( Set.of() ) .beforeDot( FormattingStyle.GapStyle.SPACE ) .alignPrefixes( FormattingStyle.Alignment.OFF ) + .insertFinalNewline( false ) .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); @@ -62,6 +64,7 @@ public void testPrefixAlignmentRight() { .knownPrefixes( Set.of() ) .beforeDot( FormattingStyle.GapStyle.SPACE ) .alignPrefixes( FormattingStyle.Alignment.RIGHT ) + .insertFinalNewline( false ) .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); @@ -159,6 +162,53 @@ public void testPredicateAlignmentWithFirstPredicateInNewLine() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testPredicateAndObjectAlignment() { + final String modelString = """ + @prefix xsd: . + @prefix : . + + :foo1 :bar 1 ; + :bar234 2 ; + :bar567890 3 . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( false ) + .alignPredicates( true ) + .alignObjects( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testPredicateAndObjectAlignmentWithFirstPredicateInNewLine() { + final String modelString = """ + @prefix xsd: . + @prefix : . + + :foo1 + :bar 1 ; + :bar234 2 ; + :bar567890 3 . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( true ) + .alignPredicates( true ) + .alignObjects( true ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + @Test public void testMultipleReferencedAnonNodes() { // Note how the anonymous node can not be serialized using [ ] because it is referenced multiple times. From c866a2359485d55955291867f00e0ffd5622a6db Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 05:39:25 +0100 Subject: [PATCH 015/280] Fix indentation calculation In top-level anonymous nodes this could have been negative for continuation indents --- src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index e93c8f9f..4eebe0c4 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -184,7 +184,7 @@ private String indent( final int level ) { case SPACE -> " ".repeat( style.indentSize ); case TAB -> "\\t"; }; - return singleIndent.repeat( level ); + return singleIndent.repeat( Math.max( level, 0 ) ); } private String continuationIndent( final int level ) { From ecc27e480cee35ed1da53955cd8f1a682eee2827 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 05:43:41 +0100 Subject: [PATCH 016/280] Limit value space for property-based tests --- .../formatter/TurtleFormatterPropertyTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index 2b1cc30f..ca001dbc 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -27,7 +27,7 @@ public class TurtleFormatterPropertyTest { @Provide Arbitrary anyString() { - return Arbitraries.strings().ofMaxLength( 10 ); + return Arbitraries.strings().ofMaxLength( 5 ); } @Provide @@ -59,7 +59,7 @@ Arbitrary anyDoubleLiteral() { @Provide Arbitrary anyIntLiteral() { - return Arbitraries.integers() + return Arbitraries.integers().between( -5, 5 ) .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDint ) ); } @@ -90,8 +90,10 @@ Arbitrary anyUnsignedByteLiteral() { @Provide Arbitrary anyLiteral() { return Arbitraries - .oneOf( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), anyDoubleLiteral(), - anyIntLiteral(), anyLongLiteral(), anyShortLiteral(), anyByteLiteral(), anyUnsignedByteLiteral() ); + .oneOf( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), anyDoubleLiteral() + , + anyIntLiteral(), anyLongLiteral(), anyShortLiteral(), anyByteLiteral(), anyUnsignedByteLiteral() + ); } @Provide @@ -106,7 +108,7 @@ Arbitrary anyUrl() { @Provide Arbitrary anyUrn() { - return Arbitraries.integers().map( number -> "urn:ex:" + number ); + return Arbitraries.integers().between( 0, 100 ).map( number -> "urn:ex:" + number ); } @Provide @@ -161,7 +163,7 @@ Arbitrary anyModel() { } ); } - @Property + @Property( tries = 50 ) public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) final Model model ) { final String result = formatter.apply( model ); final Model newModel = ModelFactory.createDefaultModel(); From bd9821671fc0e658ab9d025005039cd7a9524088 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 05:48:58 +0100 Subject: [PATCH 017/280] Fix indendation with tabs --- .../java/de/atextor/turtle/formatter/TurtleFormatter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 4eebe0c4..aaea573b 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -182,7 +182,7 @@ private State writePrefixes( final State state ) { private String indent( final int level ) { final String singleIndent = switch ( style.indentStyle ) { case SPACE -> " ".repeat( style.indentSize ); - case TAB -> "\\t"; + case TAB -> "\t"; }; return singleIndent.repeat( Math.max( level, 0 ) ); } @@ -190,7 +190,7 @@ private String indent( final int level ) { private String continuationIndent( final int level ) { final String continuation = switch ( style.indentStyle ) { case SPACE -> " ".repeat( style.continuationIndentSize ); - case TAB -> "\\t".repeat( 2 ); + case TAB -> "\t".repeat( 2 ); }; return indent( level - 1 ) + continuation; } From 7ae9827d7a5e17daee089bb6654c1f4a6141984f Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 05:49:13 +0100 Subject: [PATCH 018/280] Add test for tab indentation --- .../turtle/formatter/TurtleFormatterTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 79f3db0d..7ef98d75 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -135,6 +135,28 @@ public void testPredicateAlignmentWithFirstPredicateInSameLine() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testIndentationWithTabs() { + final String modelString = """ + @prefix xsd: . + @prefix : . + + :foo1 :bar1 1 ; + \t:bar2 2 ; + \t:bar3 3 . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .firstPredicateInNewLine( false ) + .indentStyle( FormattingStyle.IndentStyle.TAB ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + @Test public void testPredicateAlignmentWithFirstPredicateInNewLine() { final String modelString = """ From 43febbfe93dcab1590b0741bfa02a8ad0be82b2b Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 06:15:06 +0100 Subject: [PATCH 019/280] Add Jabel annotation processor to create Java 11 build --- build.gradle.kts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 6af1194f..bb575e7b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,6 +17,8 @@ dependencies { implementation("io.vavr:vavr:0.10.3") implementation("org.slf4j:slf4j-api:1.7.30") + annotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1") testImplementation("org.assertj:assertj-core:3.19.0") testImplementation("net.jqwik:jqwik:1.3.10") @@ -41,15 +43,21 @@ tasks.named("dependencyUpdates", DependencyUpdatesTask::class.java).configure { } } +tasks.withType().configureEach { + options.compilerArgs.addAll(arrayOf("--release", "11")) +} + tasks { compileJava { options.encoding = "UTF-8" sourceCompatibility = "15" + targetCompatibility = "11" } compileTestJava { options.encoding = "UTF-8" sourceCompatibility = "15" + targetCompatibility = "11" } test { From f0523bd2cf060792d49a545f3a83f6cf681057b7 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 06:15:40 +0100 Subject: [PATCH 020/280] Update Jqwik --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index bb575e7b..c4256980 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1") testImplementation("org.assertj:assertj-core:3.19.0") - testImplementation("net.jqwik:jqwik:1.3.10") + testImplementation("net.jqwik:jqwik:1.4.0") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1") } From bfa53c7fc0844f9a9009c99c4163a00753e1feba Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 06:15:57 +0100 Subject: [PATCH 021/280] Write Jacoco HTML report --- build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index c4256980..89141b9a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -76,6 +76,8 @@ tasks { reports { xml.isEnabled = true xml.destination = file("${buildDir}/reports/jacoco/report.xml") + html.isEnabled = true + html.destination = file("${buildDir}/reports/jacoco/html-report") } } } From 7d900e7dbe1ff563651800fe2a9a2757c93589e9 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 06:22:08 +0100 Subject: [PATCH 022/280] Add build action --- .github/workflows/main-build.yml | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/main-build.yml diff --git a/.github/workflows/main-build.yml b/.github/workflows/main-build.yml new file mode 100644 index 00000000..49f48751 --- /dev/null +++ b/.github/workflows/main-build.yml @@ -0,0 +1,44 @@ +name: Main build + +on: + push: + branches: 'master' + tags-ignore: + - 'v**' + pull_request: + branches: '*' + +jobs: + build: + runs-on: ${{ matrix.os }}-latest + timeout-minutes: 15 + strategy: + matrix: + java: [ 15 ] + os: [ ubuntu, macos ] + name: with Java ${{ matrix.java }} on ${{ matrix.os }} + steps: + - name: Check out repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set up java + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Cache Gradle + uses: actions/cache@v2 + with: + path: ~/.gradle/caches/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ${{ runner.os }}-gradle- + - name: Gradle build + run: ./gradlew clean build jacocoTestReport --stacktrace + + buildDone: + name: buildOk + needs: build + runs-on: ubuntu-latest + steps: + - name: buildOk + run: echo 'all builds passed' From 7a8a56b1897c5da19e5ef4c00476a247cd41aa35 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 06:55:38 +0100 Subject: [PATCH 023/280] Fix branch name in build workflow --- .github/workflows/main-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main-build.yml b/.github/workflows/main-build.yml index 49f48751..612e82c9 100644 --- a/.github/workflows/main-build.yml +++ b/.github/workflows/main-build.yml @@ -2,7 +2,7 @@ name: Main build on: push: - branches: 'master' + branches: 'main' tags-ignore: - 'v**' pull_request: From 3625d094687ac48238b62612ad062a178bf48d2d Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 07:08:59 +0100 Subject: [PATCH 024/280] Remove macos build from matrix Can't reproduce it locally due to lack of a mac --- .github/workflows/main-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main-build.yml b/.github/workflows/main-build.yml index 612e82c9..2b68986a 100644 --- a/.github/workflows/main-build.yml +++ b/.github/workflows/main-build.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: java: [ 15 ] - os: [ ubuntu, macos ] + os: [ ubuntu ] name: with Java ${{ matrix.java }} on ${{ matrix.os }} steps: - name: Check out repo From f90a5ffe7ae71075921890f5f06f53b403a8c862 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 07:45:24 +0100 Subject: [PATCH 025/280] Use Jabel annotation processor for tests --- build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 89141b9a..f16c661f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,6 +23,8 @@ dependencies { testImplementation("org.assertj:assertj-core:3.19.0") testImplementation("net.jqwik:jqwik:1.4.0") + testAnnotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1") } From e1aacead582404928bb706c672c4e662a926012e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 19:51:29 +0100 Subject: [PATCH 026/280] Temporarily disable property-based test due to memory restrictions --- .../atextor/turtle/formatter/TurtleFormatterPropertyTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index ca001dbc..ff38c465 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -3,6 +3,7 @@ import net.jqwik.api.Arbitraries; import net.jqwik.api.Arbitrary; import net.jqwik.api.Combinators; +import net.jqwik.api.Disabled; import net.jqwik.api.ForAll; import net.jqwik.api.Property; import net.jqwik.api.Provide; @@ -22,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.fail; +@Disabled( "current implementation requires too much heap space" ) public class TurtleFormatterPropertyTest { private final TurtleFormatter formatter = new TurtleFormatter( FormattingStyle.builder().build() ); From 341c4e951e8936b41aa83dd949487dc935a77552 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 19 Feb 2021 21:03:24 +0100 Subject: [PATCH 027/280] Rename build workflow --- .github/workflows/{main-build.yml => build.yml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{main-build.yml => build.yml} (95%) diff --git a/.github/workflows/main-build.yml b/.github/workflows/build.yml similarity index 95% rename from .github/workflows/main-build.yml rename to .github/workflows/build.yml index 2b68986a..f6614d67 100644 --- a/.github/workflows/main-build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Main build +name: build on: push: @@ -15,7 +15,7 @@ jobs: strategy: matrix: java: [ 15 ] - os: [ ubuntu ] + os: [ ubuntu, macos ] name: with Java ${{ matrix.java }} on ${{ matrix.os }} steps: - name: Check out repo From 55158bc80660005f65629bfbd0f8d828d8292eed Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 22 Feb 2021 07:05:49 +0100 Subject: [PATCH 028/280] Add writing to OutputStream --- .../turtle/formatter/TurtleFormatter.java | 69 ++++++++++++++----- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index aaea573b..dde86dfc 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -24,18 +24,28 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.util.Comparator; +import java.util.function.BiConsumer; import java.util.function.Function; -public class TurtleFormatter implements Function { +public class TurtleFormatter implements Function, BiConsumer { + private static final Logger LOG = LoggerFactory.getLogger( TurtleFormatter.class ); + public static final String OUTPUT_ERROR_MESSAGE = "Could not write to stream"; + private final FormattingStyle style; private final String beforeDot; private final String endOfLine; + private final java.nio.charset.Charset encoding; + private final Comparator> prefixOrder; private final Comparator objectOrder; @@ -55,6 +65,13 @@ public TurtleFormatter( final FormattingStyle style ) { case NEWLINE -> endOfLine; }; + encoding = switch ( style.charset ) { + case UTF_8, UTF_8_BOM -> StandardCharsets.UTF_8; + case LATIN1 -> StandardCharsets.ISO_8859_1; + case UTF_16_BE -> StandardCharsets.UTF_16BE; + case UTF_16_LE -> StandardCharsets.UTF_16LE; + }; + prefixOrder = Comparator.>comparingInt( entry -> style.prefixOrder.contains( entry._1() ) ? style.prefixOrder.indexOf( entry._1() ) : @@ -72,13 +89,31 @@ private static List statements( final Model model ) { return List.ofAll( model.listStatements().toList() ); } - private static List statements( final Model model, final Resource subject, final Property predicate, - final RDFNode object ) { - return List.ofAll( model.listStatements( subject, predicate, object ).toList() ); + private static List statements( final Model model, final Property predicate, final RDFNode object ) { + return List.ofAll( model.listStatements( null, predicate, object ).toList() ); } @Override public String apply( final Model model ) { + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + accept( model, outputStream ); + return outputStream.toString(); + } + + private void writeByteOrderMark( final OutputStream outputStream ) { + try { + outputStream.write( new byte[]{ (byte) 0xEF, (byte) 0xBB, (byte) 0xBF } ); + } catch ( final IOException exception ) { + LOG.error( OUTPUT_ERROR_MESSAGE, exception ); + } + } + + @Override + public void accept( final Model model, final OutputStream outputStream ) { + if ( style.charset == FormattingStyle.Charset.UTF_8_BOM ) { + writeByteOrderMark( outputStream ); + } + final PrefixMapping prefixMapping = buildPrefixMapping( model ); final Comparator predicateOrder = Comparator.comparingInt( property -> @@ -91,7 +126,7 @@ public String apply( final Model model ) { .ofAll( anonymousResourcesThatNeedAnId( model ) ) .zipWithIndex() .map( entry -> new Tuple2<>( entry._1(), style.anonymousNodeIdGenerator.apply( entry._1(), entry._2() ) ) ) - .foldLeft( new State( model, predicateOrder, prefixMapping ), ( state, entry ) -> + .foldLeft( new State( outputStream, model, predicateOrder, prefixMapping ), ( state, entry ) -> state.withIdentifiedAnonymousResource( entry._1(), entry._2() ) ); final State prefixesWritten = writePrefixes( initialState ); @@ -101,7 +136,7 @@ public String apply( final Model model ) { prefixMapping.shortForm( statement.getSubject().getURI() ) : statement.getSubject().toString() ); final List wellKnownSubjects = List.ofAll( style.subjectOrder ).flatMap( subjectType -> - statements( model, null, RDF.type, subjectType ).sorted( subjectComparator ) ); + statements( model, RDF.type, subjectType ).sorted( subjectComparator ) ); final List otherSubjects = statements( model ) .filter( statement -> !statement.getPredicate().equals( RDF.type ) ) .sorted( subjectComparator ); @@ -136,8 +171,6 @@ public String apply( final Model model ) { LOG.debug( "Written {} resources, with {} named anonymous resources", finalState.visitedResources.size(), finalState.identifiedAnonymousResources.size() ); - - return finalState.print(); } /** @@ -152,7 +185,7 @@ private Set anonymousResourcesThatNeedAnId( final Model model ) { .filter( RDFNode::isResource ) .map( RDFNode::asResource ) .filter( RDFNode::isAnon ) - .filter( object -> statements( model, null, null, object ).toList().size() > 1 ) + .filter( object -> statements( model, null, object ).toList().size() > 1 ) .toSet(); } @@ -462,7 +495,7 @@ private State writeProperty( final Resource subject, final Property predicate, f @With @AllArgsConstructor private class State { - StringBuffer buffer; + OutputStream outputStream; Model model; @@ -478,9 +511,9 @@ private class State { int alignment; - public State( final Model model, final Comparator predicateOrder, + public State( final OutputStream outputStream, final Model model, final Comparator predicateOrder, final PrefixMapping prefixMapping ) { - this( new StringBuffer(), model, HashSet.empty(), HashMap.empty(), predicateOrder, prefixMapping, 0, 0 ); + this( outputStream, model, HashSet.empty(), HashMap.empty(), predicateOrder, prefixMapping, 0, 0 ); } public State withIdentifiedAnonymousResource( final Resource anonymousResource, final String id ) { @@ -504,14 +537,12 @@ public State newLine() { } public State write( final String content ) { - // Interface pretends to use immutable data structures, while the implementation actually reuses the - // same StringBuffer - buffer.append( content ); + try { + outputStream.write( content.getBytes( encoding ) ); + } catch ( final IOException e ) { + LOG.error( OUTPUT_ERROR_MESSAGE, e ); + } return withAlignment( alignment + content.length() ); } - - public String print() { - return buffer.toString(); - } } } From 013752b2f485457b7c25449387cb9e359497dc7e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 22 Feb 2021 07:20:14 +0100 Subject: [PATCH 029/280] Add README --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..e40fb5b9 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# turtle-formatter + +[![build](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) + +**turtle-formatter** is a Java library for pretty printing +[RDF/Turtle](https://www.w3.org/TR/turtle/) documents in a _configurable_ and _reproducible_ way. + +It takes as input a formatting style and an [Apache Jena](https://jena.apache.org) Model and +produces as output a pretty-printed RDF/Turtle document. + +## Usage + +```java +import de.atextor.turtle.formatter.FormattingStyle; +import de.atextor.turtle.formatter.TurtleFormatter; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.riot.RDFDataMgr; + +// ... + +TurtleFormatter formatter = new TurtleFormatter(FormattingStyle.DEFAULT); +// Build or load a Jena Model +Model model = RDFDataMgr.loadModel("data.ttl"); +// Either create a string... +String prettyPrintedModel = formatter.apply(model); +// ...or write directly to an OutputStream +formatter.accept(model, System.out); +``` + +## Contact + +**turtle-formatter** is developed by Andreas Textor <>. + From 965e06a8ce4d2739ba0c6ce009637928a1df6593 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 26 Feb 2021 06:01:37 +0100 Subject: [PATCH 030/280] Remove not yet implemented method --- .../java/de/atextor/turtle/formatter/FormattingStyle.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index 0cae4131..3d9cf715 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -1,9 +1,7 @@ package de.atextor.turtle.formatter; -import io.vavr.control.Try; import lombok.Builder; import lombok.Value; -import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.RDFNode; import org.apache.jena.rdf.model.Resource; @@ -202,10 +200,6 @@ public class FormattingStyle { @Builder.Default BiFunction anonymousNodeIdGenerator = ( resource, integer ) -> "_:gen" + integer; - public static Try fromModel( final Model model ) { - return null; - } - public enum Alignment { LEFT, OFF, From 3c74c706c0071b4e15672583118136463aca1385 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 26 Feb 2021 06:02:16 +0100 Subject: [PATCH 031/280] Configure build for performing releases --- build.gradle.kts | 131 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 104 insertions(+), 27 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f16c661f..ef22370c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,8 +6,14 @@ plugins { id("com.github.ben-manes.versions") version "0.36.0" id("com.adarshr.test-logger") version "2.1.1" id("io.franzbecker.gradle-lombok") version "4.0.0" + `java-library` + `maven-publish` + signing } +group = "de.atextor" +description = "Library for pretty printing RDF/Turtle documents" + repositories { mavenCentral() } @@ -28,8 +34,9 @@ dependencies { testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1") } -jacoco { - toolVersion = "0.8.6" +java { + withJavadocJar() + withSourcesJar() } fun isNonStable(version: String): Boolean { @@ -49,37 +56,107 @@ tasks.withType().configureEach { options.compilerArgs.addAll(arrayOf("--release", "11")) } -tasks { - compileJava { - options.encoding = "UTF-8" - sourceCompatibility = "15" - targetCompatibility = "11" - } +tasks.compileJava { + options.encoding = "UTF-8" + sourceCompatibility = "15" + targetCompatibility = "11" +} - compileTestJava { - options.encoding = "UTF-8" - sourceCompatibility = "15" - targetCompatibility = "11" - } +tasks.compileTestJava { + options.encoding = "UTF-8" + sourceCompatibility = "15" + targetCompatibility = "11" +} + +tasks.test { + useJUnitPlatform() + ignoreFailures = false + failFast = true + maxHeapSize = "1G" +} + +jacoco { + toolVersion = "0.8.6" +} - test { - useJUnitPlatform() - ignoreFailures = false - failFast = true +tasks.jacocoTestReport { + reports { + xml.isEnabled = true + xml.destination = file("${buildDir}/reports/jacoco/report.xml") + html.isEnabled = true + html.destination = file("${buildDir}/reports/jacoco/html-report") } +} - javadoc { - (options as CoreJavadocOptions).addStringOption("Xdoclint:accessibility,html,syntax,reference", "-quiet") - options.encoding = "UTF-8" - shouldRunAfter(test) +tasks.javadoc { + (options as CoreJavadocOptions).addStringOption("Xdoclint:accessibility,html,syntax,reference", "-quiet") + options.encoding = "UTF-8" + if (JavaVersion.current().isJava9Compatible) { + (options as StandardJavadocDocletOptions).addBooleanOption("html5", true) } + shouldRunAfter(tasks.test) +} - jacocoTestReport { - reports { - xml.isEnabled = true - xml.destination = file("${buildDir}/reports/jacoco/report.xml") - html.isEnabled = true - html.destination = file("${buildDir}/reports/jacoco/html-report") +publishing { + publications { + create("mavenJava") { + artifactId = "turtle-formatter" + from(components["java"]) + versionMapping { + usage("java-api") { + fromResolutionOf("runtimeClasspath") + } + usage("java-runtime") { + fromResolutionResult() + } + } + pom { + name.set("turtle-formatter") + description.set(project.description) + url.set("https://github.com/atextor/turtle-formatter") + licenses { + license { + name.set("GNU Lesser General Public Public License Version 3") + url.set("https://www.gnu.org/licenses/lgpl-3.0") + } + } + developers { + developer { + id.set("atextor") + name.set("Andreas Textor") + email.set("mail@atextor.de") + } + } + scm { + connection.set("scm:git:git://github.com/atextor/turtle-formatter.git") + developerConnection.set("scm:git:ssh://github.com:atextor/turtle-formatter.git") + url.set("https://github.com/atextor/turtle-formatter/tree/main") + } + issueManagement { + url.set("https://github.com/atextor/turtle-formatter/issues") + system.set("GitHub") + } + } + } + } + repositories { + maven { + name = "OSSRH" + url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") + credentials { + username = System.getenv("MAVEN_USERNAME") + password = System.getenv("MAVEN_PASSWORD") + } } } } + +// This configuration will read the signing PGP key and password from environment variables +// ORG_GRADLE_PROJECT_signingKey (in ASCII-armored format) and ORG_GRADLE_PROJECT_signingPassword +signing { + val signingKey: String? by project + val signingPassword: String? by project + useInMemoryPgpKeys(signingKey, signingPassword) + sign(publishing.publications["mavenJava"]) +} + From 730f2036b50f79b108dd3ac2ca2a4d3fe7683a36 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 26 Feb 2021 06:05:06 +0100 Subject: [PATCH 032/280] Add release and push workflows --- .github/workflows/push-to-central.yml | 35 +++++++++++++++++++++++++++ .github/workflows/release.yml | 24 ++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 .github/workflows/push-to-central.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/push-to-central.yml b/.github/workflows/push-to-central.yml new file mode 100644 index 00000000..d93afd7c --- /dev/null +++ b/.github/workflows/push-to-central.yml @@ -0,0 +1,35 @@ +name: release + +on: + release: + types: [created] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Check out repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set up java + uses: actions/setup-java@v1 + with: + java-version: 15 + - name: Cache Gradle + uses: actions/cache@v2 + with: + path: ~/.gradle/caches/ + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Gradle build + run: | + echo ${{ github.event.release.tag_name }} | sed 's/v/version=/g' > gradle.properties + ./gradlew publish --no-daemon + env: + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }} + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }} + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..c923fbab --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +name: release + +on: + push: + branches: + - master + +jobs: + build: + name: Create GitHub Release + runs-on: ubuntu-latest + steps: + - uses: ChanTsune/release-with-commit@v2.0.1 + with: + regexp: "Release (\\d+([.]\\d+)*)\n*((\\s|\\S)+)" + regexp_options: "us" + release_name: "version $1" + tag_name: "v$1" + body: "$3" + draft: false + prerelease: false + env: + GITHUB_TOKEN: '${{secrets.GITHUB_TOKEN}}' + From e357bb05c92307606aeefe13edda33b6a25ff95c Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 2 Mar 2021 05:00:50 +0100 Subject: [PATCH 033/280] Release 1.0.0 This is the first feature-complete version. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e40fb5b9..dad22b8b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.org) Model and produces as output a pretty-printed RDF/Turtle document. +## Current Status + +The library is feature-complete. + ## Usage ```java From 0872bd6181cd6e4007a1102fa87c76489ae99d50 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 2 Mar 2021 05:06:58 +0100 Subject: [PATCH 034/280] Fix branch name in release workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c923fbab..f7ffe1d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ name: release on: push: branches: - - master + - main jobs: build: From ddcd76e6b28374da766dc68775ce88ab979745f2 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 2 Mar 2021 05:11:57 +0100 Subject: [PATCH 035/280] Release 1.0.0 This is the first feature-complete version. --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f6614d67..c527f6ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: matrix: java: [ 15 ] os: [ ubuntu, macos ] - name: with Java ${{ matrix.java }} on ${{ matrix.os }} + name: With Java ${{ matrix.java }} on ${{ matrix.os }} steps: - name: Check out repo uses: actions/checkout@v2 @@ -36,9 +36,9 @@ jobs: run: ./gradlew clean build jacocoTestReport --stacktrace buildDone: - name: buildOk + name: Build Ok needs: build runs-on: ubuntu-latest steps: - - name: buildOk + - name: Build Ok run: echo 'all builds passed' From 393b3e7391a235b7c4f35c2fed12711ff049aa74 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 2 Mar 2021 05:43:37 +0100 Subject: [PATCH 036/280] Use github PAT instead of token This is to enable build automation where one action creates a release and another action has a trigger on it, see https://github.community/t/github-action-trigger-on-release-not-working-if-releases-was-created-by-automation/16559 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f7ffe1d1..93a9f3d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,5 +20,5 @@ jobs: draft: false prerelease: false env: - GITHUB_TOKEN: '${{secrets.GITHUB_TOKEN}}' + GITHUB_TOKEN: '${{ secrets._GITHUB_PAT }}' From bf061f1c20e49e7cb1930cef87eac2853a60a9bb Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 2 Mar 2021 05:47:13 +0100 Subject: [PATCH 037/280] Release 1.0.0 This is the first feature-complete version. --- .github/workflows/push-to-central.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-to-central.yml b/.github/workflows/push-to-central.yml index d93afd7c..f613913b 100644 --- a/.github/workflows/push-to-central.yml +++ b/.github/workflows/push-to-central.yml @@ -1,4 +1,4 @@ -name: release +name: push-to-central on: release: From ae92876680956022ba4b8da991abaefa92292de1 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 3 Mar 2021 06:06:04 +0100 Subject: [PATCH 038/280] Update README with release and documentation --- README.md | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dad22b8b..6c469fb0 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,72 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.org) Model and produces as output a pretty-printed RDF/Turtle document. -## Current Status +**Current Status**: The library is feature-complete. -The library is feature-complete. +## Why? + +Every RDF library comes with its own serializers, for example an Apache Jena Model can be written +[in multiple ways](https://jena.apache.org/documentation/io/rdf-output.html), the easiest being +calling the write method on a model itself: `model.write(System.out, "TURTLE")`. However, due to the +nature of RDF, outgoing edges of a node in the graph have no order. When serializing a model, there +are multiple valid ways to do so. For example, the following two models are identical: + + + + + + +
+ +```turtle +@prefix : . + +:test + :blorb "blorb" ; + :floop "floop" . +``` + + + +```turtle +@prefix : . + +:test + :floop "floop" ; + :blorb "blorb" . +``` + +
+ +Therefore, when a model is serialized, one of many different (valid) serializations could be the +result. This is a problem when different versions of a model file are compared, for example when +used as artifacts in a git repository. Additionally, serialized files are often formatted in one +style hardcoded in the respective library. So while Apache Jena and for example +[libraptor2](http://librdf.org/raptor/) both write valid RDF/Turtle, the files are formatted +differently. You would not want the code of a project formatted differently in different files, +would you? +**turtle-formatter** addreses these problems by taking care of serialization order and providing a +way to customize the formatting style. ## Usage +### Add dependency + +Add the following dependency to your Maven `pom.xml`: +```xml + + de.atextor + turtle-formatter + 1.0.0 + +``` + +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.0.0'` + +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.0.0")` + +### Calling the formatter + ```java import de.atextor.turtle.formatter.FormattingStyle; import de.atextor.turtle.formatter.TurtleFormatter; @@ -31,6 +91,93 @@ String prettyPrintedModel = formatter.apply(model); formatter.accept(model, System.out); ``` +### Customizing the style + +Instead of passing `FormattingStyle.DEFAULT`, you can create a custom `FormattingStyle` object. + +```java +FormattingStyle style = FormattingStyle.builder(). ... .build(); +``` + +The following options can be set on the FormattingStyle builder: + + + + + + + + + + + + + + + + + + + + + + + + + +
OptionDescriptionDefault
+ +`indentStyle` + + + +`SPACE` or `TAB`. Note that when choosing `TAB`, `alignPredicates` and `alignObjects` must be `false`. + +SPACE
+ +`alignPrefixes` + +Boolean. Example: + +```turtle +# true +@prefix rdf: . +@prefix example: . + +# false +@prefix rdf: . +@prefix example: . +``` + +false
+ +`alignPredicates` + + +Boolean. Example: + +```turtle +# alignPredicates true +:test a rdf:Resource ; + :blorb "blorb" ; + :floop "floop" . + +# alignPredicates false and firstPredicateInNewLine true +:test + a rdf:Resource ; + :blorb "blorb" ; + :floop "floop" . + +# alignPredicates false and firstPredicateInNewLine false +:test a rdf:Resource ; + :blorb "blorb" ; + :floop "floop" . +``` + +false
+ +*The remaining missing documentation will be added soon* + ## Contact **turtle-formatter** is developed by Andreas Textor <>. From dc57e0553a90b99a06a7752dff757c44f358e5b4 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 4 Mar 2021 05:45:57 +0100 Subject: [PATCH 039/280] Document more FormatterStyle options --- README.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 6c469fb0..c92c042d 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ style hardcoded in the respective library. So while Apache Jena and for example [libraptor2](http://librdf.org/raptor/) both write valid RDF/Turtle, the files are formatted differently. You would not want the code of a project formatted differently in different files, would you? -**turtle-formatter** addreses these problems by taking care of serialization order and providing a +**turtle-formatter** addresses these problems by taking care of serialization order and providing a way to customize the formatting style. ## Usage @@ -111,19 +111,6 @@ The following options can be set on the FormattingStyle builder: -`indentStyle` - - - - -`SPACE` or `TAB`. Note that when choosing `TAB`, `alignPredicates` and `alignObjects` must be `false`. - - -SPACE - - - - `alignPrefixes` @@ -147,35 +134,150 @@ The following options can be set on the FormattingStyle builder: `alignPredicates` +`firstPredicateInNewLine` Boolean. Example: ```turtle -# alignPredicates true +# firstPredicateInNewLine false / alignPredicates true :test a rdf:Resource ; :blorb "blorb" ; :floop "floop" . -# alignPredicates false and firstPredicateInNewLine true +# firstPredicateInNewLine false / alignPredicates false +:test a rdf:Resource ; + :blorb "blorb" ; + :floop "floop" . + +# firstPredicateInNewLine true / alignPredicates does not matter :test a rdf:Resource ; :blorb "blorb" ; :floop "floop" . +``` + + +false (for both) + + + + + +`charset`\* + + + + +One of `LATIN1`, `UTF_16_BE`, `UTF_16_LE`, `UTF_8`, `UTF_8_BOM` + + + + +`UTF_8` + + + + + + +`doubleFormat` + + + + +A [NumberFormat](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/NumberFormat.html) that describes how `xsd:double` literals are formatted + + + + +`0.####E0` + + + + + + + +`endOfLine`\* + + + + +One of `LF`, `CR`, `CRLF`. If unsure, please see [Newline](https://en.wikipedia.org/wiki/Newline) + + + + +`LF` + + + + + + +`indentStyle`\* + + + + +`SPACE` or `TAB`. Note that when choosing `TAB`, `alignPredicates` and `alignObjects` are +automatically treated as `false`. + + + + +`SPACE` + + + + + -# alignPredicates false and firstPredicateInNewLine false +`useAForRdfType` + + + + +Boolean. Determines whether `rdf:type` is written as `a` or as `rdf:type`. + + + +true + + + + + + +`useCommaByDefault` + + + + +Boolean. Determines whether to use commas for identical predicates. Example: +```turtle +# useCommaByDefault false :test a rdf:Resource ; - :blorb "blorb" ; - :floop "floop" . + :blorb "someBlorb" ; + :blorb "anotherBlorb" . + +# useCommaByDefault true +:test a rdf:Resource ; + :blorb "someBlorb", "anotherBlorb" . ``` -false + +false + +\* Adapted from [EditorConfig](https://editorconfig.org/#file-format-details) + *The remaining missing documentation will be added soon* ## Contact From 3094732c88702bd590b7fe40244deb38ec0e0cb7 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Mar 2021 07:05:17 +0100 Subject: [PATCH 040/280] Document more FormatterStyle options --- README.md | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 149 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c92c042d..814af493 100644 --- a/README.md +++ b/README.md @@ -148,14 +148,14 @@ Boolean. Example: # firstPredicateInNewLine false / alignPredicates false :test a rdf:Resource ; - :blorb "blorb" ; - :floop "floop" . + :blorb "blorb" ; + :floop "floop" . # firstPredicateInNewLine true / alignPredicates does not matter :test - a rdf:Resource ; - :blorb "blorb" ; - :floop "floop" . + a rdf:Resource ; + :blorb "blorb" ; + :floop "floop" . ``` @@ -165,6 +165,35 @@ Boolean. Example: +`alignObjects` + + + + +Boolean. Example: +```turtle +# alignObjects true +:test + a rdf:Resource ; + :blorb "blorb" ; + :floopfloop "floopfloop" . + +# alignObjects false +:test + a rdf:Resource ; + :blorb "blorb" ; + :floopfloop "floopfloop" . +``` + + + +false + + + + + + `charset`\* @@ -232,6 +261,37 @@ automatically treated as `false`. + + + + +`indentSize`\* + + + + +Integer. When using `indentStyle` `SPACE`, defines the indentation size. + + + +2 + + + + + + +`insertFinalNewLine`\* + + + +Boolean. Determines whether there is a line break after the last line + + +true + + + @@ -260,12 +320,12 @@ Boolean. Determines whether to use commas for identical predicates. Example: ```turtle # useCommaByDefault false :test a rdf:Resource ; - :blorb "someBlorb" ; - :blorb "anotherBlorb" . + :blorb "someBlorb" ; + :blorb "anotherBlorb" . # useCommaByDefault true :test a rdf:Resource ; - :blorb "someBlorb", "anotherBlorb" . + :blorb "someBlorb", "anotherBlorb" . ``` @@ -274,6 +334,87 @@ false + + + +`commaForPredicate` + + + + +A set of predicates that, when used multiple times, are separated by commas, even when +`useCommaByDefault` is `false`. Example: + +```turtle +# useCommaByDefault false, commaForPredicate contains 'rdf:type', +# firstPredicateInNewLine true +:test a ex:something, owl:NamedIndividual ; + :blorb "someBlorb" ; + :blorb "anotherBlorb" . + +# useCommaByDefault false, commaForPredicate is empty, +# firstPredicateInNewLine false +:test + a ex:something ; + a owl:NamedIndividual ; + :blorb "someBlorb" ; + :blorb "anotherBlorb" . +``` + + + + +Set.of(`rdf:type`) + + + + + + + +`noCommaForPredicate` + + + + +Analogous to `commaForPredicate`: A set of predicates that, when used multiple times, are _not_ +separated by commas, even when `useCommaByDefault` is `true`. + + + +Empty + + + + + + +`prefixOrder` + + + + +A list of namespace prefixes that defines the order of `@prefix` directives. Namespaces from the +list always appear first (in this order), every other prefix will appear afterwards, +lexicographically sorted. Example: + +```turtle +# prefixOrder contains "rdf" and "owl" (in this order), so they +# will appear in this order at the top (when the model contains +# them!), followed by all other namespaces +@prefix rdf: . +@prefix owl: . +@prefix example: . +``` + + + + +List.of(`rdf` `rdfs` `xsd` `owl`) + + + + \* Adapted from [EditorConfig](https://editorconfig.org/#file-format-details) From 877c5c6cc00e2ef1f5e15b94dca79535bf01183b Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 9 Mar 2021 06:05:33 +0100 Subject: [PATCH 041/280] Document missing FormattingStyle options --- README.md | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 144 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 814af493..03c554ba 100644 --- a/README.md +++ b/README.md @@ -134,24 +134,28 @@ The following options can be set on the FormattingStyle builder: `alignPredicates` -`firstPredicateInNewLine` +`firstPredicate`- +`InNewLine` Boolean. Example: ```turtle -# firstPredicateInNewLine false / alignPredicates true +# firstPredicateInNewLine false +# alignPredicates true :test a rdf:Resource ; :blorb "blorb" ; :floop "floop" . -# firstPredicateInNewLine false / alignPredicates false +# firstPredicateInNewLine false +# alignPredicates false :test a rdf:Resource ; :blorb "blorb" ; :floop "floop" . -# firstPredicateInNewLine true / alignPredicates does not matter +# firstPredicateInNewLine true +# alignPredicates does not matter :test a rdf:Resource ; :blorb "blorb" ; @@ -346,8 +350,8 @@ A set of predicates that, when used multiple times, are separated by commas, eve `useCommaByDefault` is `false`. Example: ```turtle -# useCommaByDefault false, commaForPredicate contains 'rdf:type', -# firstPredicateInNewLine true +# useCommaByDefault false, commaForPredicate contains +# 'rdf:type', firstPredicateInNewLine true :test a ex:something, owl:NamedIndividual ; :blorb "someBlorb" ; :blorb "anotherBlorb" . @@ -399,9 +403,9 @@ list always appear first (in this order), every other prefix will appear afterwa lexicographically sorted. Example: ```turtle -# prefixOrder contains "rdf" and "owl" (in this order), so they -# will appear in this order at the top (when the model contains -# them!), followed by all other namespaces +# prefixOrder contains "rdf" and "owl" (in this order), so +# they will appear in this order at the top (when the model +# contains them!), followed by all other namespaces @prefix rdf: . @prefix owl: . @prefix example: . @@ -415,12 +419,141 @@ List.of(`rdf` `rdfs` `xsd` `owl`) + + + +`subjectOrder` + + + + +A list of resources that determines the order in which subjects appear. For a subject `s` there must +exist a statement `s rdf:type t` in the model and an entry for `t` in the `subjectOrder` list for +the element to be considered in the ordering, i.e., when `subjectOrder` contains `:Foo` and `:Bar` +in that order, the pretty-printed model will show first all `:Foo`s, then all `:Bar`s, then +everything else lexicographically sorted. + + + + +List.of(`owl:Ontology` `owl:Class` `owl:ObjectProperty` `owl:DatatypeProperty` +`owl:AnnotationProperty` `owl:NamedIndividual` `owl:AllDifferent` `owl:Axiom`) + + + + + + + +`predicateOrder` + + + + +A list of properties that determine the order in which predicates appear for a subject. First all +properties that are in the list are shown in that order, then everything else lexicographically +sorted. For example, when `predicateOrder` contains `:z`, `:y`, `:x` in that order and the subject +has statements for the properties `:a`, `:x` and `:z`: + +```turtle +:test + :z "z" ; + :x "x" ; + :a "a" . +``` + + + + +List.of(`rdf:type`) + + + + + + + +`objectOrder` + + + + +A list of RDFNodes (i.e. resources or literals) that determine the order in which objects appear for +a predicate, when there are multiple statements with the same subject and the same predicate. First +all objects that are in the list are shown in that order, then everything else lexicographically +sorted. For example, when `objectOrder` contains `:Foo` and `:Bar` in that order: + +```turtle +:test a :Foo, :Bar . +``` + + + + +List.of(`owl:NamedIndividual` `owl:ObjectProperty` `owl:DatatypeProperty` `owl:AnnotationProperty` `owl:FunctionalProperty` `owl:InverseFunctionalProperty` `owl:TransitiveProperty` `owl:SymmetricProperty` `owl:AsymmetricProperty` `owl:ReflexiveProperty` `owl:IrreflexiveProperty`) + + + + + + + +`anonymousNode`- +`IdGenerator` + + + + +A `BiFunction` that takes a resource (blank node) and an integer (counter) and determines the name +for a blank node in the formatted output, if it needs to be locally named. Consider the following +model: + +```turtle +:test :foo _:b0 . +:test2 :bar _:b0 . +``` + +There is no way to serialize this model in RDF/Turtle while using the inline blank node syntax `[ ]` +for the anonymous node `_:b0`. In this case, the anonymousNodeIdGenerator is called to determine +the name of the blank node in the output. + + + + +`(r, i) -> "_:gen" + i` + + + + + + + +{`after`,`before`} +{`Opening`, `Closing`} +{`Parenthesis`, `SquareBrackets`}, + +{`after`,`before`} +{`Comma`, `Dot`, `Semicolon` } + + + + +`NEWLINE`, `NOTHING` or `SPACE`. Various options for formatting gaps and line breaks. It is not +recommended to change those, as the default style represents the commonly accepted best practices +for formatting turtle already. + + + + +Varied + + + + \* Adapted from [EditorConfig](https://editorconfig.org/#file-format-details) -*The remaining missing documentation will be added soon* - ## Contact **turtle-formatter** is developed by Andreas Textor <>. From d8c372a8e105b0bec041c4855ec80506e977589f Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 10 Mar 2021 05:37:26 +0100 Subject: [PATCH 042/280] Upload code coverage on build --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c527f6ec..a52bb2df 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,6 +34,12 @@ jobs: restore-keys: ${{ runner.os }}-gradle- - name: Gradle build run: ./gradlew clean build jacocoTestReport --stacktrace + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + directory: ./build/test-results/test/ + name: codecov-umbrella + verbose: true buildDone: name: Build Ok From d4c4a182b0f5f428267e9dc3afa822a945a304c3 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 10 Mar 2021 05:40:22 +0100 Subject: [PATCH 043/280] Fix codecov config --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a52bb2df..9d3b3767 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,6 @@ jobs: - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 with: - directory: ./build/test-results/test/ name: codecov-umbrella verbose: true From 32dfed6bb4c7ce23bc1f3e2770e7f8f817c9d036 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 10 Mar 2021 05:44:58 +0100 Subject: [PATCH 044/280] Add matrix information to code coverage upload --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9d3b3767..b169f86c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,9 @@ jobs: matrix: java: [ 15 ] os: [ ubuntu, macos ] + env: + OS: ${{ matrix.os }} + USED_JAVA: ${{ matrix.java }} name: With Java ${{ matrix.java }} on ${{ matrix.os }} steps: - name: Check out repo @@ -38,6 +41,7 @@ jobs: uses: codecov/codecov-action@v1 with: name: codecov-umbrella + env_vars: OS,USED_JAVA verbose: true buildDone: From 570a45ad79308e98f691b662200e07de45c0cc28 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 10 Mar 2021 05:45:57 +0100 Subject: [PATCH 045/280] Disable verbose output for codecov --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b169f86c..bbf11a64 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,7 +42,6 @@ jobs: with: name: codecov-umbrella env_vars: OS,USED_JAVA - verbose: true buildDone: name: Build Ok From 00febda996ae3e7eb910c58235a7ca63d6673c0d Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 10 Mar 2021 05:50:33 +0100 Subject: [PATCH 046/280] Add test to format a more complex document --- .../turtle/formatter/TurtleFormatterTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 7ef98d75..7c4befee 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -284,6 +284,19 @@ public void testTopLevelAnonymousNode() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testFormatting() { + final Model model = ModelFactory.createDefaultModel(); + model.read( "http://purl.org/atextor/ontology/turtle-formatting", "TURTLE" ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = modelFromString( result ); + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + + } + private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); From 1301c8a336cc1572ca6dbef2e2ce20275d2d88fc Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 10 Mar 2021 05:52:44 +0100 Subject: [PATCH 047/280] Add codecov badge to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 03c554ba..596fd3a2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # turtle-formatter -[![build](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) +[![build](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/atextor/turtle-formatter/branch/main/graph/badge.svg?token=X2YFDI4Z4W)](https://codecov.io/gh/atextor/turtle-formatter) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) **turtle-formatter** is a Java library for pretty printing [RDF/Turtle](https://www.w3.org/TR/turtle/) documents in a _configurable_ and _reproducible_ way. From 7f0933aa1be1d7c71512f8f1734bcda4d90fc75e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 10 Mar 2021 05:58:58 +0100 Subject: [PATCH 048/280] Add lombok config This is to tell Jacoco about code generated by lombok, to exclude it from coverage/reports --- lombok.config | 1 + 1 file changed, 1 insertion(+) create mode 100644 lombok.config diff --git a/lombok.config b/lombok.config new file mode 100644 index 00000000..8f7e8aa1 --- /dev/null +++ b/lombok.config @@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation = true \ No newline at end of file From 4e5d6ab91cc9497982af8cc230210180743af589 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 12 Mar 2021 05:47:39 +0100 Subject: [PATCH 049/280] Add test for UTF_8_BOM Charset --- .../turtle/formatter/TurtleFormatterTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 7c4befee..80049298 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -7,6 +7,7 @@ import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; @@ -284,6 +285,18 @@ public void testTopLevelAnonymousNode() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testUtf8BomCharset() { + final Model model = prefixModel(); + final FormattingStyle style = FormattingStyle.builder() + .charset( FormattingStyle.Charset.UTF_8_BOM ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + formatter.accept( model, outputStream ); + assertThat( outputStream.toByteArray() ).startsWith( (byte) 0xEF, (byte) 0xBB, (byte) 0xBF ); + } + @Test public void testFormatting() { final Model model = ModelFactory.createDefaultModel(); From 48ccafafb000e58a88ad1479712e62abd6f1ffdd Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 12 Mar 2021 05:51:46 +0100 Subject: [PATCH 050/280] Enable Property-based Test --- .../TurtleFormatterPropertyTest.java | 55 ++++++------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index ff38c465..93473bd0 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -3,7 +3,6 @@ import net.jqwik.api.Arbitraries; import net.jqwik.api.Arbitrary; import net.jqwik.api.Combinators; -import net.jqwik.api.Disabled; import net.jqwik.api.ForAll; import net.jqwik.api.Property; import net.jqwik.api.Provide; @@ -23,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.fail; -@Disabled( "current implementation requires too much heap space" ) public class TurtleFormatterPropertyTest { private final TurtleFormatter formatter = new TurtleFormatter( FormattingStyle.builder().build() ); @@ -53,49 +51,30 @@ Arbitrary anyFloatLiteral() { .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDfloat ) ); } + @Provide Arbitrary anyDoubleLiteral() { return Arbitraries.doubles() .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDdouble ) ); } + // Providing only one for each of the integer number types is sufficient for testing the formatter + // as there is no variation in their serialzition, but greatly reduces the test space @Provide - Arbitrary anyIntLiteral() { - return Arbitraries.integers().between( -5, 5 ) - .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDint ) ); - } - - @Provide - Arbitrary anyLongLiteral() { - return Arbitraries.longs() - .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDlong ) ); - } - - @Provide - Arbitrary anyShortLiteral() { - return Arbitraries.shorts() - .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDshort ) ); - } - - @Provide - Arbitrary anyByteLiteral() { - return Arbitraries.bytes() - .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDbyte ) ); - } - - @Provide - Arbitrary anyUnsignedByteLiteral() { - return Arbitraries.integers().between( 0, 255 ) - .map( value -> ResourceFactory.createTypedLiteral( value.toString(), XSDDatatype.XSDunsignedByte ) ); + Arbitrary anyIntegerNumberLiteral() { + return Arbitraries.of( + ResourceFactory.createTypedLiteral( "1", XSDDatatype.XSDint ), + ResourceFactory.createTypedLiteral( "2", XSDDatatype.XSDlong ), + ResourceFactory.createTypedLiteral( "3", XSDDatatype.XSDbyte ), + ResourceFactory.createTypedLiteral( "4", XSDDatatype.XSDbyte ), + ResourceFactory.createTypedLiteral( "5", XSDDatatype.XSDunsignedByte ) + ); } @Provide Arbitrary anyLiteral() { - return Arbitraries - .oneOf( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), anyDoubleLiteral() - , - anyIntLiteral(), anyLongLiteral(), anyShortLiteral(), anyByteLiteral(), anyUnsignedByteLiteral() - ); + return Arbitraries.oneOf( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), anyDoubleLiteral(), + anyIntegerNumberLiteral() ); } @Provide @@ -105,12 +84,12 @@ Arbitrary anyAnonymousResource() { @Provide Arbitrary anyUrl() { - return Arbitraries.integers().between( 0, 100 ).map( number -> "http://example.com/" + number ); + return Arbitraries.integers().between( 0, 10 ).map( number -> "http://example.com/" + number ); } @Provide Arbitrary anyUrn() { - return Arbitraries.integers().between( 0, 100 ).map( number -> "urn:ex:" + number ); + return Arbitraries.integers().between( 0, 10 ).map( number -> "urn:ex:" + number ); } @Provide @@ -142,7 +121,7 @@ Arbitrary anyStatement( final Model model ) { @Provide Arbitrary anyList( final Model model ) { final Supplier> elements = () -> anyRdfNode( model ); - return Arbitraries.lazyOf( elements, elements ).list().ofMaxSize( 10 ) + return Arbitraries.lazyOf( elements, elements ).list().ofMaxSize( 3 ) .map( list -> model.createList( list.iterator() ) ); } @@ -165,7 +144,7 @@ Arbitrary anyModel() { } ); } - @Property( tries = 50 ) + @Property( tries = 300 ) public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) final Model model ) { final String result = formatter.apply( model ); final Model newModel = ModelFactory.createDefaultModel(); From dda81c999b533117cdd528ffae8c64ccc71744c3 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 12 Mar 2021 06:01:12 +0100 Subject: [PATCH 051/280] Use formatting style variations in property-based test --- .../TurtleFormatterPropertyTest.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index 93473bd0..55226e99 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -23,8 +23,6 @@ import static org.junit.jupiter.api.Assertions.fail; public class TurtleFormatterPropertyTest { - private final TurtleFormatter formatter = new TurtleFormatter( FormattingStyle.builder().build() ); - @Provide Arbitrary anyString() { return Arbitraries.strings().ofMaxLength( 5 ); @@ -135,6 +133,23 @@ Arbitrary> anyListOfStatements( final Model model ) { return anyStatement( model ).list().ofMaxSize( 5 ); } + // Creates styles for some of the options that control the actual formatting and are difficult to test + // in isolation. + @Provide + Arbitrary anyStyle() { + final Arbitrary onOff = Arbitraries.of( true, false ); + + return Combinators.combine( onOff, onOff, onOff, onOff, onOff ) + .as( ( firstPredicateInNewLine, useAForRdfType, useComma, alignPredicates, alignObjects ) -> + FormattingStyle.builder() + .firstPredicateInNewLine( firstPredicateInNewLine ) + .useAForRdfType( useAForRdfType ) + .useCommaByDefault( useComma ) + .alignPredicates( alignPredicates ) + .alignObjects( alignObjects ) + .build() ); + } + @Provide Arbitrary anyModel() { final Model model = ModelFactory.createDefaultModel(); @@ -145,7 +160,9 @@ Arbitrary anyModel() { } @Property( tries = 300 ) - public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) final Model model ) { + public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) final Model model, + @ForAll( "anyStyle" ) final FormattingStyle style ) { + final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); final Model newModel = ModelFactory.createDefaultModel(); try { From 2ae94f0c066715bf5ee92833a9fd61c51fa8fa80 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 26 Mar 2021 06:07:15 +0100 Subject: [PATCH 052/280] Change Jena dependency to jena-core apache-jena-libs is a `pom` type dependency, while jena-core is of type `jar`. This change makes possible to properly use turtle-formatter as a maven dependency itself without having to override the jena dependency. --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index ef22370c..96132e38 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,7 @@ repositories { } dependencies { - implementation("org.apache.jena:apache-jena-libs:3.17.0") + implementation("org.apache.jena:jena-core:3.17.0") implementation("io.vavr:vavr:0.10.3") implementation("org.slf4j:slf4j-api:1.7.30") From 325c64e443a0196b75440521ba71c58facfe3414 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 26 Mar 2021 06:18:38 +0100 Subject: [PATCH 053/280] Remove implicit dependency to jena-arq --- .../atextor/turtle/formatter/TurtleFormatterPropertyTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index 55226e99..e6f693b8 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -14,7 +14,6 @@ import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.ResourceFactory; import org.apache.jena.rdf.model.Statement; -import org.apache.jena.riot.RDFLanguages; import java.io.StringReader; import java.util.List; @@ -166,7 +165,7 @@ public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) fin final String result = formatter.apply( model ); final Model newModel = ModelFactory.createDefaultModel(); try { - newModel.read( new StringReader( result ), "", RDFLanguages.strLangTurtle ); + newModel.read( new StringReader( result ), "", "TURTLE" ); } catch ( final RuntimeException e ) { fail(); } From d3a478fa076e3502be13f984e536a84d91e9ed9c Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 26 Mar 2021 06:18:52 +0100 Subject: [PATCH 054/280] Fix test that breaks due to HTTP forwarding --- .../java/de/atextor/turtle/formatter/TurtleFormatterTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 80049298..64a5d8d0 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -300,7 +300,8 @@ public void testUtf8BomCharset() { @Test public void testFormatting() { final Model model = ModelFactory.createDefaultModel(); - model.read( "http://purl.org/atextor/ontology/turtle-formatting", "TURTLE" ); + model + .read( "https://raw.githubusercontent.com/atextor/turtle-formatting/main/turtle-formatting.ttl", "TURTLE" ); final FormattingStyle style = FormattingStyle.builder().build(); final TurtleFormatter formatter = new TurtleFormatter( style ); From 5771cd0e3f4781c2bae5a80d3fe945402c168f13 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 26 Mar 2021 06:43:00 +0100 Subject: [PATCH 055/280] Release 1.0.1 This is a maintenance release, which does not add features. It fixes the dependency declarations that prevented the previous version to be used as Maven depenency without custom overrides. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 596fd3a2..8304361a 100644 --- a/README.md +++ b/README.md @@ -64,13 +64,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.0.0 + 1.0.1 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.0.0'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.0.1'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.0.0")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.0.1")` ### Calling the formatter From f94a509c7448f61a0761c662efd0b85ff4141130 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 16 Apr 2021 05:38:34 +0200 Subject: [PATCH 056/280] Add maven central badge to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8304361a..f1f693cf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # turtle-formatter -[![build](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/atextor/turtle-formatter/branch/main/graph/badge.svg?token=X2YFDI4Z4W)](https://codecov.io/gh/atextor/turtle-formatter) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) +[![build](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/de.atextor/turtle-formatter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/de.atextor/turtle-formatter) [![codecov](https://codecov.io/gh/atextor/turtle-formatter/branch/main/graph/badge.svg?token=X2YFDI4Z4W)](https://codecov.io/gh/atextor/turtle-formatter) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) **turtle-formatter** is a Java library for pretty printing [RDF/Turtle](https://www.w3.org/TR/turtle/) documents in a _configurable_ and _reproducible_ way. From d7a54f1aa53fce4ecdcc0906edcf2b57aa12491b Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 16 Apr 2021 06:23:57 +0200 Subject: [PATCH 057/280] Add more explanation and sample to README --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f1f693cf..a844972f 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ produces as output a pretty-printed RDF/Turtle document. ## Why? +### Reproducible Formatting + Every RDF library comes with its own serializers, for example an Apache Jena Model can be written [in multiple ways](https://jena.apache.org/documentation/io/rdf-output.html), the easiest being calling the write method on a model itself: `model.write(System.out, "TURTLE")`. However, due to the @@ -55,6 +57,53 @@ would you? **turtle-formatter** addresses these problems by taking care of serialization order and providing a way to customize the formatting style. +### Nice and Configurable Formatting + +Most serializers, while creating valid RDF/Turtle, create _ugly_ formatting. Obviously, what is ugly +and what isn't is highly subjective, so this should be configurable. **turtle-formatter** addresses +this by making the formatting style configurable, e.g. how alignment should be done, where extrace +spaces should be inserted and even if indendation is using tabs or spaces. A default style is +provided that reflects sane settings (the author's opinon). An RDF document formatted using the +default style could look like this: + +```turtle +@prefix rdfs: . ① +@prefix owl: . +@prefix : . + +:Male a owl:Class ; ② + owl:disjointWith :Female ; ③ + owl:equivalentClass [ ④ + a owl:Restriction ; + owl:hasSelf true ; ⑤ + owl:onProperty :isMale ; + ] ; + rdfs:subClassOf :Person . + +:hasBrother a owl:ObjectProperty ; + owl:propertyChainAxiom ( :hasSibling :isMale ) ; ⑥ + rdfs:range :Male . + +:hasUncle a owl:ObjectProperty, owl:IrreflexiveProperty ; ⑦ + owl:propertyChainAxiom ( :hasParent :hasSibling :hasHusband ) ; ⑦ + owl:propertyChainAxiom ( :hasParent :hasBrother ) ; + rdfs:range :Male . +``` + +* ① Prefixes are sorted by common, then custom. They are _not_ aligned on the colon because that + looks bad when one prefix string is much longer than the others. +* ② `rdf:type` is always written as `a`. It is always the first predicate and written in the same + line as the subject. +* ③ Indentation is done using a fixed size, like in any other format or language. Predicates are not + aligned to subjects with an arbitrary length. +* ④ Anonymous nodes are written using the `[ ]` notation whenever possible. +* ⑤ Literal shortcuts are used where possible (e.g. no `"true"^^xsd:boolean`). +* ⑥ RDF Lists are always written using the `( )` notation, no blank node IDs or + `rdf:next`/`rdf:first` seen here. +* ⑦ The same predicates on the same subjects are repeated rather than using the `,` notation, + because especially when the objects are longer (nested anonymous nodes), it is difficult to + understand. The exception to this rule is for different `rdf:type`s. + ## Usage ### Add dependency @@ -148,13 +197,13 @@ Boolean. Example: :blorb "blorb" ; :floop "floop" . -# firstPredicateInNewLine false +# firstPredicateInNewLine false # alignPredicates false :test a rdf:Resource ; :blorb "blorb" ; :floop "floop" . -# firstPredicateInNewLine true +# firstPredicateInNewLine true # alignPredicates does not matter :test a rdf:Resource ; @@ -458,7 +507,7 @@ has statements for the properties `:a`, `:x` and `:z`: ```turtle :test :z "z" ; - :x "x" ; + :x "x" ; :a "a" . ``` @@ -557,4 +606,3 @@ Varied ## Contact **turtle-formatter** is developed by Andreas Textor <>. - From c9c95718fd1c3e2eb2f81c0ab5812f0ac19834b2 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 05:09:07 +0200 Subject: [PATCH 058/280] Bugfix: Also serialize subjects with rdf:types not in subjectOrder --- .../turtle/formatter/TurtleFormatter.java | 4 ++- .../turtle/formatter/TurtleFormatterTest.java | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index dde86dfc..6f689c68 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -138,7 +138,9 @@ public void accept( final Model model, final OutputStream outputStream ) { final List wellKnownSubjects = List.ofAll( style.subjectOrder ).flatMap( subjectType -> statements( model, RDF.type, subjectType ).sorted( subjectComparator ) ); final List otherSubjects = statements( model ) - .filter( statement -> !statement.getPredicate().equals( RDF.type ) ) + .filter( statement -> !( statement.getPredicate().equals( RDF.type ) + && statement.getObject().isResource() + && style.subjectOrder.contains( statement.getObject().asResource() ) ) ) .sorted( subjectComparator ); final List statements = wellKnownSubjects.appendAll( otherSubjects ) .filter( statement -> !( statement.getSubject().isAnon() diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 64a5d8d0..04ce2337 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -311,6 +311,33 @@ public void testFormatting() { } + @Test + public void testSubjectsNotInSubjectOrder() { + final String modelString = """ + @prefix : . + @prefix rdfs: . + @prefix rdf: . + + :Person a rdfs:Class . + :name a rdf:Property . + :address a rdf:Property . + :city a rdf:Property . + :Max a :Person ; + :name "Max" ; + :address [ + :city "City Z" + ] . + """; + + final Model model = modelFromString( modelString ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = modelFromString( result ); + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + } + private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); From e27fe4bda280fd300a2181626e1153c13984eee2 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 05:14:50 +0200 Subject: [PATCH 059/280] Add rdfs:Class and rdf:Property to default subjectOrder --- README.md | 5 +++-- .../java/de/atextor/turtle/formatter/FormattingStyle.java | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a844972f..fd4bb8a8 100644 --- a/README.md +++ b/README.md @@ -485,8 +485,9 @@ everything else lexicographically sorted. -List.of(`owl:Ontology` `owl:Class` `owl:ObjectProperty` `owl:DatatypeProperty` -`owl:AnnotationProperty` `owl:NamedIndividual` `owl:AllDifferent` `owl:Axiom`) +List.of(`rdfs:Class` `owl:Ontology` `owl:Class` `rdf:Property` `owl:ObjectProperty` +`owl:DatatypeProperty` `owl:AnnotationProperty` `owl:NamedIndividual` `owl:AllDifferent` +`owl:Axiom`) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index 3d9cf715..f7a61aaf 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -167,8 +167,10 @@ public class FormattingStyle { @Builder.Default List subjectOrder = List.of( + RDFS.Class, OWL2.Ontology, OWL2.Class, + RDF.Property, OWL2.ObjectProperty, OWL2.DatatypeProperty, OWL2.AnnotationProperty, From 40813d6b70c3126eb7260cadb5178868534a7734 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 05:16:15 +0200 Subject: [PATCH 060/280] Add rdfs:label, comment, dct:description to default predicateOrder --- README.md | 2 +- .../java/de/atextor/turtle/formatter/FormattingStyle.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fd4bb8a8..bba14c3a 100644 --- a/README.md +++ b/README.md @@ -515,7 +515,7 @@ has statements for the properties `:a`, `:x` and `:z`: -List.of(`rdf:type`) +List.of(`rdf:type` `rdfs:label` `rdfs:comment` `dcterms:description`) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index f7a61aaf..c3f1f15b 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -181,7 +181,10 @@ public class FormattingStyle { @Builder.Default List predicateOrder = List.of( - RDF.type + RDF.type, + RDFS.label, + RDFS.comment, + DCTerms.description ); @Builder.Default From e4904ae1650fa0fae4bca0709424cc371ed17e6a Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 06:02:28 +0200 Subject: [PATCH 061/280] Add new option `keepUnusedPrefixes` --- README.md | 16 ++++++++++++ .../turtle/formatter/FormattingStyle.java | 3 +++ .../turtle/formatter/TurtleFormatter.java | 25 +++++++++++++++++-- .../turtle/formatter/TurtleFormatterTest.java | 8 +++--- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bba14c3a..afbfbb9d 100644 --- a/README.md +++ b/README.md @@ -364,6 +364,22 @@ true +`keepUnusedPrefixes` + + + + +Boolean. If `true`, keeps prefixes that are not part of any statement. + + + +false + + + + + + `useCommaByDefault` diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index c3f1f15b..8723ebc4 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -157,6 +157,9 @@ public class FormattingStyle { @Builder.Default boolean trimTrailingWhitespace = true; + @Builder.Default + boolean keepUnusedPrefixes = false; + @Builder.Default List prefixOrder = List.of( "rdf", diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 6f689c68..75eab776 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -7,6 +7,7 @@ import io.vavr.collection.Map; import io.vavr.collection.Set; import io.vavr.collection.Stream; +import io.vavr.control.Option; import lombok.AllArgsConstructor; import lombok.Value; import lombok.With; @@ -208,12 +209,32 @@ private State writePrefixes( final State state ) { case RIGHT -> "@prefix %" + maxPrefixLength + "s: <%s>" + beforeDot + ".%n"; }; - final State prefixesWritten = prefixes.toStream().sorted( prefixOrder ).foldLeft( state, - ( newState, entry ) -> newState.write( String.format( prefixFormat, entry._1(), entry._2() ) ) ); + final List urisInModel = allUsedUris( state.model ); + final State prefixesWritten = prefixes.toStream().sorted( prefixOrder ) + .filter( entry -> style.keepUnusedPrefixes || + urisInModel.find( resource -> resource.startsWith( entry._2() ) ).isDefined() ) + .foldLeft( state, ( newState, entry ) -> + newState.write( String.format( prefixFormat, entry._1(), entry._2() ) ) ); return prefixesWritten.newLine(); } + private List allUsedUris( final Model model ) { + return List.ofAll( model::listStatements ) + .flatMap( statement -> List.of( statement.getSubject(), statement.getPredicate(), statement.getObject() ) ) + .>map( rdfNode -> { + if ( rdfNode.isURIResource() ) { + return Option.of( rdfNode.asResource().getURI() ); + } + if ( rdfNode.isLiteral() ) { + return Option.of( rdfNode.asLiteral().getDatatypeURI() ); + } + return Option.none(); + } ) + .filter( Option::isDefined ) + .map( Option::get ); + } + private String indent( final int level ) { final String singleIndent = switch ( style.indentStyle ) { case SPACE -> " ".repeat( style.indentSize ); diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 04ce2337..614b487d 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -24,6 +24,7 @@ public void testPrefixAlignmentLeft() { .beforeDot( FormattingStyle.GapStyle.SPACE ) .alignPrefixes( FormattingStyle.Alignment.LEFT ) .insertFinalNewline( false ) + .keepUnusedPrefixes( true ) .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); @@ -45,6 +46,7 @@ public void testPrefixAlignmentOff() { .beforeDot( FormattingStyle.GapStyle.SPACE ) .alignPrefixes( FormattingStyle.Alignment.OFF ) .insertFinalNewline( false ) + .keepUnusedPrefixes( true ) .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); @@ -66,6 +68,7 @@ public void testPrefixAlignmentRight() { .beforeDot( FormattingStyle.GapStyle.SPACE ) .alignPrefixes( FormattingStyle.Alignment.RIGHT ) .insertFinalNewline( false ) + .keepUnusedPrefixes( true ) .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); @@ -113,7 +116,6 @@ public void testLiterals() { @Test public void testPredicateAlignmentWithFirstPredicateInSameLine() { final String modelString = """ - @prefix xsd: . @prefix : . :foo1 :bar1 1 ; @@ -139,7 +141,6 @@ public void testPredicateAlignmentWithFirstPredicateInSameLine() { @Test public void testIndentationWithTabs() { final String modelString = """ - @prefix xsd: . @prefix : . :foo1 :bar1 1 ; @@ -161,7 +162,6 @@ public void testIndentationWithTabs() { @Test public void testPredicateAlignmentWithFirstPredicateInNewLine() { final String modelString = """ - @prefix xsd: . @prefix : . :foo1 @@ -188,7 +188,6 @@ public void testPredicateAlignmentWithFirstPredicateInNewLine() { @Test public void testPredicateAndObjectAlignment() { final String modelString = """ - @prefix xsd: . @prefix : . :foo1 :bar 1 ; @@ -211,7 +210,6 @@ public void testPredicateAndObjectAlignment() { @Test public void testPredicateAndObjectAlignmentWithFirstPredicateInNewLine() { final String modelString = """ - @prefix xsd: . @prefix : . :foo1 From 1a236839936da78444600722f81537807fb46326 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 06:03:19 +0200 Subject: [PATCH 062/280] Add release notes to README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index afbfbb9d..6cd99b19 100644 --- a/README.md +++ b/README.md @@ -620,6 +620,11 @@ Varied \* Adapted from [EditorConfig](https://editorconfig.org/#file-format-details) +## Release Notes + +* 1.0.1: Fix POM so that dependency can be used as jar +* 1.0.0: First version + ## Contact **turtle-formatter** is developed by Andreas Textor <>. From 8322023c659cefebf8cfc582a0d3fcaef739f605 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 06:05:27 +0200 Subject: [PATCH 063/280] Release 1.1.0 * Bugfix: Subjects with a `rdf:type` not in `subjectOrder` are rendered correctly * Adjust default `subjectOrder` and `predicateOrder` * Add new option `keepUnusedPrefixes` and by default render only used prefixes --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6cd99b19..69238bfb 100644 --- a/README.md +++ b/README.md @@ -622,6 +622,10 @@ Varied ## Release Notes +* 1.1.0: + * Bugfix: Subjects with a `rdf:type` not in `subjectOrder` are rendered correctly + * Adjust default `subjectOrder` and `predicateOrder` + * Add new option `keepUnusedPrefixes` and by default render only used prefixes * 1.0.1: Fix POM so that dependency can be used as jar * 1.0.0: First version From bb987a35cb422fb469793ffdaa45996637b211e0 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 06:11:14 +0200 Subject: [PATCH 064/280] Release 1.1.0 Bugfix: Subjects with a `rdf:type` not in `subjectOrder` are rendered correctly. Adjust default `subjectOrder` and `predicateOrder`. Add new option `keepUnusedPrefixes` and by default render only used prefixes. From 8de83cd4445fe7e6f4d392b4a959eb9cf9639341 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 06:17:11 +0200 Subject: [PATCH 065/280] Update version in usage in README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 69238bfb..1c0bbc0b 100644 --- a/README.md +++ b/README.md @@ -113,13 +113,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.0.1 + 1.1.0 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.0.1'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.1.0'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.0.1")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.1.0")` ### Calling the formatter From 506a4d05c4d52422312ba199e37a04c81f4c1b19 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Apr 2021 08:36:38 +0200 Subject: [PATCH 066/280] Fix typos in README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1c0bbc0b..e820a0e8 100644 --- a/README.md +++ b/README.md @@ -61,10 +61,10 @@ way to customize the formatting style. Most serializers, while creating valid RDF/Turtle, create _ugly_ formatting. Obviously, what is ugly and what isn't is highly subjective, so this should be configurable. **turtle-formatter** addresses -this by making the formatting style configurable, e.g. how alignment should be done, where extrace +this by making the formatting style configurable, e.g. how alignment should be done, where extra spaces should be inserted and even if indendation is using tabs or spaces. A default style is -provided that reflects sane settings (the author's opinon). An RDF document formatted using the -default style could look like this: +provided that reflects sane settings (i.e., the author's opinion). An RDF document formatted using +the default style could look like this: ```turtle @prefix rdfs: . ① From 2e1030565bac95e0a30ca936d665b52785280131 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 10 May 2021 05:12:16 +0200 Subject: [PATCH 067/280] Make FormattingStyle fields public --- .../turtle/formatter/FormattingStyle.java | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index 8723ebc4..8d00b7f6 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -43,7 +43,7 @@ public class FormattingStyle { public static final KnownPrefix PREFIX_EX = new KnownPrefix( "ex", URI.create( "http://example.org/" ) ); @Builder.Default - Set knownPrefixes = Set.of( + public Set knownPrefixes = Set.of( PREFIX_RDF, PREFIX_RDFS, PREFIX_XSD, @@ -53,115 +53,115 @@ public class FormattingStyle { ); @Builder.Default - GapStyle afterClosingParenthesis = GapStyle.NOTHING; + public GapStyle afterClosingParenthesis = GapStyle.NOTHING; @Builder.Default - GapStyle afterClosingSquareBracket = GapStyle.SPACE; + public GapStyle afterClosingSquareBracket = GapStyle.SPACE; @Builder.Default - GapStyle afterComma = GapStyle.SPACE; + public GapStyle afterComma = GapStyle.SPACE; @Builder.Default - GapStyle afterDot = GapStyle.NEWLINE; + public GapStyle afterDot = GapStyle.NEWLINE; @Builder.Default - GapStyle afterOpeningParenthesis = GapStyle.SPACE; + public GapStyle afterOpeningParenthesis = GapStyle.SPACE; @Builder.Default - GapStyle afterOpeningSquareBracket = GapStyle.NEWLINE; + public GapStyle afterOpeningSquareBracket = GapStyle.NEWLINE; @Builder.Default - GapStyle afterSemicolon = GapStyle.NEWLINE; + public GapStyle afterSemicolon = GapStyle.NEWLINE; @Builder.Default - Alignment alignPrefixes = Alignment.OFF; + public Alignment alignPrefixes = Alignment.OFF; @Builder.Default - GapStyle beforeClosingParenthesis = GapStyle.SPACE; + public GapStyle beforeClosingParenthesis = GapStyle.SPACE; @Builder.Default - GapStyle beforeClosingSquareBracket = GapStyle.NEWLINE; + public GapStyle beforeClosingSquareBracket = GapStyle.NEWLINE; @Builder.Default - GapStyle beforeComma = GapStyle.NOTHING; + public GapStyle beforeComma = GapStyle.NOTHING; @Builder.Default - GapStyle beforeDot = GapStyle.SPACE; + public GapStyle beforeDot = GapStyle.SPACE; @Builder.Default - GapStyle beforeOpeningParenthesis = GapStyle.SPACE; + public GapStyle beforeOpeningParenthesis = GapStyle.SPACE; @Builder.Default - GapStyle beforeOpeningSquareBracket = GapStyle.SPACE; + public GapStyle beforeOpeningSquareBracket = GapStyle.SPACE; @Builder.Default - GapStyle beforeSemicolon = GapStyle.SPACE; + public GapStyle beforeSemicolon = GapStyle.SPACE; @Builder.Default - Charset charset = Charset.UTF_8; + public Charset charset = Charset.UTF_8; @Builder.Default - NumberFormat doubleFormat = new DecimalFormat( "0.####E0" ); + public NumberFormat doubleFormat = new DecimalFormat( "0.####E0" ); @Builder.Default - EndOfLineStyle endOfLine = EndOfLineStyle.LF; + public EndOfLineStyle endOfLine = EndOfLineStyle.LF; @Builder.Default - IndentStyle indentStyle = IndentStyle.SPACE; + public IndentStyle indentStyle = IndentStyle.SPACE; @Builder.Default - WrappingStyle wrapListItems = WrappingStyle.FOR_LONG_LINES; + public WrappingStyle wrapListItems = WrappingStyle.FOR_LONG_LINES; @Builder.Default - boolean firstPredicateInNewLine = false; + public boolean firstPredicateInNewLine = false; @Builder.Default - boolean useAForRdfType = true; + public boolean useAForRdfType = true; @Builder.Default - boolean useCommaByDefault = false; + public boolean useCommaByDefault = false; @Builder.Default - Set commaForPredicate = Set.of( RDF.type ); + public Set commaForPredicate = Set.of( RDF.type ); @Builder.Default - Set noCommaForPredicate = Set.of(); + public Set noCommaForPredicate = Set.of(); @Builder.Default - boolean useShortLiterals = true; + public boolean useShortLiterals = true; @Builder.Default - boolean alignBaseIRI = false; + public boolean alignBaseIRI = false; @Builder.Default - boolean alignObjects = false; + public boolean alignObjects = false; @Builder.Default - boolean alignPredicates = false; + public boolean alignPredicates = false; @Builder.Default - int continuationIndentSize = 4; + public int continuationIndentSize = 4; @Builder.Default - boolean indentPrediates = true; + public boolean indentPrediates = true; @Builder.Default - boolean insertFinalNewline = true; + public boolean insertFinalNewline = true; @Builder.Default - int indentSize = 2; + public int indentSize = 2; @Builder.Default - int maxLineLength = 100; + public int maxLineLength = 100; @Builder.Default - boolean trimTrailingWhitespace = true; + public boolean trimTrailingWhitespace = true; @Builder.Default - boolean keepUnusedPrefixes = false; + public boolean keepUnusedPrefixes = false; @Builder.Default - List prefixOrder = List.of( + public List prefixOrder = List.of( "rdf", "rdfs", "xsd", @@ -169,7 +169,7 @@ public class FormattingStyle { ); @Builder.Default - List subjectOrder = List.of( + public List subjectOrder = List.of( RDFS.Class, OWL2.Ontology, OWL2.Class, @@ -183,7 +183,7 @@ public class FormattingStyle { ); @Builder.Default - List predicateOrder = List.of( + public List predicateOrder = List.of( RDF.type, RDFS.label, RDFS.comment, @@ -191,7 +191,7 @@ public class FormattingStyle { ); @Builder.Default - List objectOrder = List.of( + public List objectOrder = List.of( OWL2.NamedIndividual, OWL2.ObjectProperty, OWL2.DatatypeProperty, @@ -206,7 +206,7 @@ public class FormattingStyle { ); @Builder.Default - BiFunction anonymousNodeIdGenerator = ( resource, integer ) -> "_:gen" + integer; + public BiFunction anonymousNodeIdGenerator = ( resource, integer ) -> "_:gen" + integer; public enum Alignment { LEFT, From 563cb81e4ab54ade1d1e1c6bdbf31ac8468b470e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 10 May 2021 05:21:49 +0200 Subject: [PATCH 068/280] Update gradle wrapper to 7.0 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 28ff446a..f371643e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 1b4d500dd6e175f4e1b0a3e9077305e6b1a93c6b Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 10 May 2021 05:25:57 +0200 Subject: [PATCH 069/280] Update README --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1c0bbc0b..59cb1fee 100644 --- a/README.md +++ b/README.md @@ -113,13 +113,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.1.0 + 1.1.1 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.1.0'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.1.1'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.1.0")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.1.1")` ### Calling the formatter @@ -622,6 +622,8 @@ Varied ## Release Notes +* 1.1.1: + * Make fields of `FormattingStyle` public, so that `DEFAULT` config is readable * 1.1.0: * Bugfix: Subjects with a `rdf:type` not in `subjectOrder` are rendered correctly * Adjust default `subjectOrder` and `predicateOrder` From ce2bc31502f01b73dd4c8431d1edf58b03fda9f7 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 10 May 2021 05:33:33 +0200 Subject: [PATCH 070/280] Release 1.1.1 Make fields of `FormattingStyle` public, so that `DEFAULT` config is readable From b24ec0abeb445014eff120e2a8a4feb1dd8f0e68 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 10 May 2021 06:07:42 +0200 Subject: [PATCH 071/280] Release 1.1.1 Make fields of `FormattingStyle` public, so that `DEFAULT` config is readable From 3188fdd7ff79df06e3e26d282facf77bb4c96b4b Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 18 May 2021 05:55:09 +0200 Subject: [PATCH 072/280] Remove formatting ontology from default knownPrefixes --- src/main/java/de/atextor/turtle/formatter/FormattingStyle.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index 8d00b7f6..ee8b452d 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -48,8 +48,7 @@ public class FormattingStyle { PREFIX_RDFS, PREFIX_XSD, PREFIX_OWL, - PREFIX_DCTERMS, - PREFIX_FMT + PREFIX_DCTERMS ); @Builder.Default From 52bb5737bb84f040145bb9331340c6b02ec6a10c Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 18 May 2021 05:56:52 +0200 Subject: [PATCH 073/280] Implement list line wrapping --- .../turtle/formatter/TurtleFormatter.java | 35 ++++++-- .../turtle/formatter/TurtleFormatterTest.java | 82 +++++++++++++++++++ 2 files changed, 111 insertions(+), 6 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 75eab776..4d709bff 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -35,10 +35,10 @@ public class TurtleFormatter implements Function, BiConsumer { - private static final Logger LOG = LoggerFactory.getLogger( TurtleFormatter.class ); - public static final String OUTPUT_ERROR_MESSAGE = "Could not write to stream"; + private static final Logger LOG = LoggerFactory.getLogger( TurtleFormatter.class ); + private final FormattingStyle style; private final String beforeDot; @@ -315,7 +315,10 @@ private State writeResource( final Resource resource, final State state ) { } private State writeList( final Resource resource, final State state ) { - final State opened = writeDelimiter( "(", style.beforeOpeningParenthesis, style.afterOpeningParenthesis, + final FormattingStyle.GapStyle afterOpeningParenthesis = + style.wrapListItems == FormattingStyle.WrappingStyle.ALWAYS ? FormattingStyle.GapStyle.NOTHING : + style.afterOpeningParenthesis; + final State opened = writeDelimiter( "(", style.beforeOpeningParenthesis, afterOpeningParenthesis, continuationIndent( state.indentationLevel ), state ); final java.util.List elementList = resource.as( RDFList.class ).asJavaList(); final State elementsWritten = List.ofAll( elementList ).zipWithIndex() @@ -323,12 +326,32 @@ private State writeList( final Resource resource, final State state ) { final RDFNode element = indexedElement._1(); final int index = indexedElement._2(); final boolean firstElement = index == 0; - final State spaceWritten = firstElement ? currentState : currentState.write( " " ); - return writeRdfNode( element, spaceWritten ); + return writeListElement( element, firstElement, currentState ); } ); + final State finalLineBreakWritten = style.wrapListItems == FormattingStyle.WrappingStyle.ALWAYS ? + elementsWritten.newLine().write( indent( elementsWritten.indentationLevel ) ) : elementsWritten; + return writeDelimiter( ")", style.beforeClosingParenthesis, style.afterClosingParenthesis, - continuationIndent( state.indentationLevel ), elementsWritten ); + continuationIndent( state.indentationLevel ), finalLineBreakWritten ); + } + + private State writeListElement( final RDFNode element, final boolean firstElement, final State state ) { + return switch ( style.wrapListItems ) { + case NEVER: + final State spaceWritten = firstElement ? state : state.write( " " ); + yield writeRdfNode( element, spaceWritten ); + case ALWAYS: + yield writeRdfNode( element, state.newLine().write( continuationIndent( state.indentationLevel ) ) ); + case FOR_LONG_LINES: + final int alignmentAfterElementIsWritten = writeRdfNode( element, + state.withOutputStream( OutputStream.nullOutputStream() ) ).alignment; + final boolean wouldElementExceedLineLength = + ( alignmentAfterElementIsWritten + 1 ) > style.maxLineLength; + yield writeRdfNode( element, wouldElementExceedLineLength ? + state.newLine().write( continuationIndent( state.indentationLevel ) ) : + ( firstElement ? state : state.write( " " ) ) ); + }; } private State writeAnonymousResource( final Resource resource, final State state ) { diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 614b487d..2a6e252e 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -283,6 +283,88 @@ public void testTopLevelAnonymousNode() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testListWrappingNever() { + final String modelString = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" "foo3" "foo4" ) . + """; + // Line length ruler + // ############################################### + // 1 10 20 30 40 + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .maxLineLength( 30 ) + .wrapListItems( FormattingStyle.WrappingStyle.NEVER ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testListWrappingAlways() { + final String modelString = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" "foo3" "foo4" ) . + """; + // Line length ruler + // ############################################### + // 1 10 20 30 40 + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .maxLineLength( 30 ) + .wrapListItems( FormattingStyle.WrappingStyle.ALWAYS ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + + :foo :bar ( + "foo1" + "foo2" + "foo3" + "foo4" + ) . + """; + assertThat( result.trim() ).isEqualTo( expected.trim() ); + } + + @Test + public void testListWrappingForLongLines() { + final String modelString = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" "foo3" "foo4" ) . + """; + // Line length ruler + // ############################################### + // 1 10 20 30 40 + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .maxLineLength( 30 ) + .wrapListItems( FormattingStyle.WrappingStyle.FOR_LONG_LINES ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final String expected = """ + @prefix : . + + :foo :bar ( "foo1" "foo2" + "foo3" "foo4" ) . + """; + assertThat( result.trim() ).isEqualTo( expected.trim() ); + } + @Test public void testUtf8BomCharset() { final Model model = prefixModel(); From 47eb9fa655db22cbce8b06e142961bd6b62109f2 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 18 May 2021 06:02:51 +0200 Subject: [PATCH 074/280] Add wrapListItems to README --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index b1e1448e..c28be990 100644 --- a/README.md +++ b/README.md @@ -616,6 +616,25 @@ Varied + + + +`wrapListItems` + + + + +`ALWAYS`, `NEVER` or `FOR_LONG_LINES`. Controls how line breaks are added after +elements in RDF lists. + + + + +`FOR_LONG_LINES` + + + + \* Adapted from [EditorConfig](https://editorconfig.org/#file-format-details) From 2016b0fa2d46302ca0b3be9870fa8a8e6b948a76 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 18 May 2021 06:41:47 +0200 Subject: [PATCH 075/280] Change license from LGPL 3.0 to Apache 2.0 --- LICENSE | 365 ++++++++++++++++++++++++++--------------------- README.md | 2 +- build.gradle.kts | 4 +- 3 files changed, 204 insertions(+), 167 deletions(-) diff --git a/LICENSE b/LICENSE index 0a041280..86700381 100644 --- a/LICENSE +++ b/LICENSE @@ -1,165 +1,202 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Andreas Textor + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index c28be990..8f36d037 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # turtle-formatter -[![build](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/de.atextor/turtle-formatter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/de.atextor/turtle-formatter) [![codecov](https://codecov.io/gh/atextor/turtle-formatter/branch/main/graph/badge.svg?token=X2YFDI4Z4W)](https://codecov.io/gh/atextor/turtle-formatter) [![License: LGPL v3](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) +[![build](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml/badge.svg)](https://github.com/atextor/turtle-formatter/actions/workflows/build.yml) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/de.atextor/turtle-formatter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/de.atextor/turtle-formatter) [![codecov](https://codecov.io/gh/atextor/turtle-formatter/branch/main/graph/badge.svg?token=X2YFDI4Z4W)](https://codecov.io/gh/atextor/turtle-formatter) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) **turtle-formatter** is a Java library for pretty printing [RDF/Turtle](https://www.w3.org/TR/turtle/) documents in a _configurable_ and _reproducible_ way. diff --git a/build.gradle.kts b/build.gradle.kts index 96132e38..0df06dc8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -116,8 +116,8 @@ publishing { url.set("https://github.com/atextor/turtle-formatter") licenses { license { - name.set("GNU Lesser General Public Public License Version 3") - url.set("https://www.gnu.org/licenses/lgpl-3.0") + name.set("Apache License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0") } } developers { From 30ac1357b70ac2a7159926b71a7c0092b6608615 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 18 May 2021 06:52:39 +0200 Subject: [PATCH 076/280] Update readme with license note and release notes --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8f36d037..5fb0639c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.org) Model and produces as output a pretty-printed RDF/Turtle document. +Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. + **Current Status**: The library is feature-complete. ## Why? @@ -113,13 +115,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.1.1 + 1.2.0 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.1.1'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.0'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.1.1")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.0")` ### Calling the formatter @@ -641,6 +643,9 @@ elements in RDF lists. ## Release Notes +* 1.2.0: + * Add `wrapListItems` configuration option + * Change license from LGPL 3.0 to Apache 2.0 * 1.1.1: * Make fields of `FormattingStyle` public, so that `DEFAULT` config is readable * 1.1.0: From c9ab4199d00dc15ff8398a0b3f8af2f419b4d77e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 18 May 2021 06:53:18 +0200 Subject: [PATCH 077/280] Release 1.2.0 Add wrapListItems option, change license to Apache 2.0 From 5d8fdf53ff3ac2be2386e6e03cb4761e21fc957d Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 7 Jul 2021 05:30:33 +0200 Subject: [PATCH 078/280] Refactor large method --- .../turtle/formatter/TurtleFormatter.java | 84 +++++++++++-------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 4d709bff..faa9502e 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -123,12 +123,7 @@ public void accept( final Model model, final OutputStream outputStream ) { Integer.MAX_VALUE ).thenComparing( property -> prefixMapping.shortForm( property.getURI() ) ); - final State initialState = Stream - .ofAll( anonymousResourcesThatNeedAnId( model ) ) - .zipWithIndex() - .map( entry -> new Tuple2<>( entry._1(), style.anonymousNodeIdGenerator.apply( entry._1(), entry._2() ) ) ) - .foldLeft( new State( outputStream, model, predicateOrder, prefixMapping ), ( state, entry ) -> - state.withIdentifiedAnonymousResource( entry._1(), entry._2() ) ); + final State initialState = buildInitialState( model, outputStream, prefixMapping, predicateOrder ); final State prefixesWritten = writePrefixes( initialState ); @@ -136,44 +131,65 @@ public void accept( final Model model, final OutputStream outputStream ) { Comparator.comparing( statement -> statement.getSubject().isURIResource() ? prefixMapping.shortForm( statement.getSubject().getURI() ) : statement.getSubject().toString() ); - final List wellKnownSubjects = List.ofAll( style.subjectOrder ).flatMap( subjectType -> - statements( model, RDF.type, subjectType ).sorted( subjectComparator ) ); - final List otherSubjects = statements( model ) - .filter( statement -> !( statement.getPredicate().equals( RDF.type ) - && statement.getObject().isResource() - && style.subjectOrder.contains( statement.getObject().asResource() ) ) ) - .sorted( subjectComparator ); - final List statements = wellKnownSubjects.appendAll( otherSubjects ) - .filter( statement -> !( statement.getSubject().isAnon() - && model.contains( null, null, statement.getSubject() ) ) ); + final List statements = determineStatements( model, subjectComparator ); + final State namedResourcesWritten = writeNamedResources( prefixesWritten, statements ); + final State allResourcesWritten = writeAnonymousResources( namedResourcesWritten ); + final State finalState = style.insertFinalNewline ? allResourcesWritten.newLine() : allResourcesWritten; + + LOG.debug( "Written {} resources, with {} named anonymous resources", finalState.visitedResources.size(), + finalState.identifiedAnonymousResources.size() ); + } + + private State writeAnonymousResources( final State state ) { + return List.ofAll( state.identifiedAnonymousResources.keySet() ) + .foldLeft( state, ( currentState, resource ) -> { + if ( !resource.listProperties().hasNext() ) { + return currentState; + } + return writeSubject( resource, currentState.withIndentationLevel( 0 ) ); + } ); + } - final State namedResourcesWritten = statements + private State writeNamedResources( final State state, final List statements ) { + return statements .map( Statement::getSubject ) - .foldLeft( prefixesWritten, ( state, resource ) -> { - if ( !resource.listProperties().hasNext() || state.visitedResources.contains( resource ) ) { - return state; + .foldLeft( state, ( currentState, resource ) -> { + if ( !resource.listProperties().hasNext() || currentState.visitedResources.contains( resource ) ) { + return currentState; } if ( resource.isURIResource() ) { - return writeSubject( resource, state.withIndentationLevel( 0 ) ); + return writeSubject( resource, currentState.withIndentationLevel( 0 ) ); } - final State resourceWritten = writeAnonymousResource( resource, state.withIndentationLevel( 0 ) ); - final boolean omitSpaceBeforeDelimiter = !state.identifiedAnonymousResources.keySet() + final State resourceWritten = writeAnonymousResource( resource, currentState + .withIndentationLevel( 0 ) ); + final boolean omitSpaceBeforeDelimiter = !currentState.identifiedAnonymousResources.keySet() .contains( resource ); return writeDot( resourceWritten, omitSpaceBeforeDelimiter ).newLine(); } ); + } - final State allResourcesWritten = List.ofAll( namedResourcesWritten.identifiedAnonymousResources.keySet() ) - .foldLeft( namedResourcesWritten, ( state, resource ) -> { - if ( !resource.listProperties().hasNext() ) { - return state; - } - return writeSubject( resource, state.withIndentationLevel( 0 ) ); - } ); - - final State finalState = style.insertFinalNewline ? allResourcesWritten.newLine() : allResourcesWritten; + private List determineStatements( final Model model, final Comparator subjectComparator ) { + final List wellKnownSubjects = List.ofAll( style.subjectOrder ).flatMap( subjectType -> + statements( model, RDF.type, subjectType ).sorted( subjectComparator ) ); + final List otherSubjects = statements( model ) + .filter( statement -> !( statement.getPredicate().equals( RDF.type ) + && statement.getObject().isResource() + && style.subjectOrder.contains( statement.getObject().asResource() ) ) ) + .sorted( subjectComparator ); + return wellKnownSubjects.appendAll( otherSubjects ) + .filter( statement -> !( statement.getSubject().isAnon() + && model.contains( null, null, statement.getSubject() ) ) ); + } - LOG.debug( "Written {} resources, with {} named anonymous resources", finalState.visitedResources.size(), - finalState.identifiedAnonymousResources.size() ); + private State buildInitialState( final Model model, final OutputStream outputStream, + final PrefixMapping prefixMapping, + final Comparator predicateOrder ) { + return Stream + .ofAll( anonymousResourcesThatNeedAnId( model ) ) + .zipWithIndex() + .map( entry -> new Tuple2<>( entry._1(), style.anonymousNodeIdGenerator.apply( entry._1(), entry._2() ) ) ) + .foldLeft( new State( outputStream, model, predicateOrder, prefixMapping ), ( state, entry ) -> + state.withIdentifiedAnonymousResource( entry._1(), entry._2() ) ); } /** From 927cc77c759bca97b9ad10d5b9024b6aa5328cda Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 7 Jul 2021 05:31:01 +0200 Subject: [PATCH 079/280] Prevent consecutive spaces in formatting --- .../de/atextor/turtle/formatter/TurtleFormatter.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index faa9502e..564cf746 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -271,7 +271,7 @@ private State writeDelimiter( final String delimiter, final FormattingStyle.GapS final FormattingStyle.GapStyle after, final String indentation, final State state ) { final State beforeState = switch ( before ) { - case SPACE -> state.write( " " ); + case SPACE -> state.lastCharacter.equals( " " ) ? state : state.write( " " ); case NOTHING -> state; case NEWLINE -> state.newLine().write( indentation ); }; @@ -573,9 +573,12 @@ private class State { int alignment; + String lastCharacter; + + public State( final OutputStream outputStream, final Model model, final Comparator predicateOrder, final PrefixMapping prefixMapping ) { - this( outputStream, model, HashSet.empty(), HashMap.empty(), predicateOrder, prefixMapping, 0, 0 ); + this( outputStream, model, HashSet.empty(), HashMap.empty(), predicateOrder, prefixMapping, 0, 0, "" ); } public State withIdentifiedAnonymousResource( final Resource anonymousResource, final String id ) { @@ -599,12 +602,13 @@ public State newLine() { } public State write( final String content ) { + final String end = content.length() > 0 ? content.substring( content.length() - 1 ) : ""; try { outputStream.write( content.getBytes( encoding ) ); } catch ( final IOException e ) { LOG.error( OUTPUT_ERROR_MESSAGE, e ); } - return withAlignment( alignment + content.length() ); + return withLastCharacter( end ).withAlignment( alignment + content.length() ); } } } From 35067b4291a3f21a3f4c699ac194190a74d40ac7 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 7 Jul 2021 05:44:49 +0200 Subject: [PATCH 080/280] Correctly indent predicates of top-level named bnodes --- .../atextor/turtle/formatter/TurtleFormatter.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 564cf746..8b124855 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -496,11 +496,14 @@ private State writeProperty( final Resource subject, final Property predicate, f final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine && !subject.isAnon() ? state.newLine() : state; - final boolean inBrackets = subject.isAnon() && !state.identifiedAnonymousResources.keySet().contains( subject ); - - final boolean shouldIndentFirstProperty = firstProperty && ( - ( style.firstPredicateInNewLine && !inBrackets ) || ( inBrackets && state.indentationLevel <= 1 ) ); - final boolean shouldIndentOtherProperty = !firstProperty && inBrackets; + final boolean isNamedAnon = state.identifiedAnonymousResources.keySet().contains( subject ); + final boolean inBrackets = subject.isAnon() && !isNamedAnon; + + final boolean shouldIndentFirstProperty = firstProperty && + ( ( style.firstPredicateInNewLine && !inBrackets ) + || ( inBrackets && state.indentationLevel <= 1 ) ); + final boolean shouldIndentOtherProperty = !firstProperty && + ( inBrackets || isNamedAnon ); final State indentedPredicate = shouldIndentFirstProperty || shouldIndentOtherProperty ? wrappedPredicate.write( indent( state.indentationLevel ) ) : wrappedPredicate; From 1b8d2409c1df16fdf8e83daed209f902f378bb60 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 8 Jul 2021 05:20:45 +0200 Subject: [PATCH 081/280] Add test for top level named bnodes --- .../turtle/formatter/TurtleFormatterTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 2a6e252e..2c0c63a3 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -4,6 +4,7 @@ import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.vocabulary.RDF; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; @@ -283,6 +284,35 @@ public void testTopLevelAnonymousNode() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testTopLevelIdentifiedAnonymousNodeWithMultiplePredicates() { + final String modelString = """ + @prefix : . + + :a a :type ; + :foo _:gen0 ; + :bar 1 . + + :b :foo _:gen0 . + + _:gen0 a :type ; + :foo "1" ; + :bar "2" . + """; + final Model model = modelFromString( modelString ); + + final String ex = "http://example.com/"; + final Property foo = ResourceFactory.createProperty( ex + "foo" ); + final Property bar = ResourceFactory.createProperty( ex + "bar" ); + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .predicateOrder( List.of( RDF.type, foo, bar ) ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + @Test public void testListWrappingNever() { final String modelString = """ From c5b534440a72863fbfc606c268c6fc836310f421 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 9 Jul 2021 05:39:44 +0200 Subject: [PATCH 082/280] Properly indent predicates of nested anonymous nodes --- .../turtle/formatter/TurtleFormatter.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 8b124855..ee79556d 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -448,9 +448,10 @@ private State writeSubject( final Resource resource, final State state ) { } // indent - final State indentedSubject = state.write( indent( state.indentationLevel ) ); - // subject final boolean isIdentifiedAnon = state.identifiedAnonymousResources.keySet().contains( resource ); + final boolean subjectsNeedsIdentation = !resource.isAnon() || isIdentifiedAnon; + final State indentedSubject = subjectsNeedsIdentation ? state.write( indent( state.indentationLevel ) ) : state; + // subject final State stateWithSubject = resource.isURIResource() || isIdentifiedAnon ? writeResource( resource, indentedSubject ).withVisitedResource( resource ) : indentedSubject.withVisitedResource( resource ); @@ -499,14 +500,21 @@ private State writeProperty( final Resource subject, final Property predicate, f final boolean isNamedAnon = state.identifiedAnonymousResources.keySet().contains( subject ); final boolean inBrackets = subject.isAnon() && !isNamedAnon; - final boolean shouldIndentFirstProperty = firstProperty && + final boolean shouldIndentFirstPropertyByLevel = firstProperty && ( ( style.firstPredicateInNewLine && !inBrackets ) || ( inBrackets && state.indentationLevel <= 1 ) ); - final boolean shouldIndentOtherProperty = !firstProperty && + final boolean shouldIndentOtherPropertyByLevel = !firstProperty && ( inBrackets || isNamedAnon ); - final State indentedPredicate = shouldIndentFirstProperty || shouldIndentOtherProperty ? + + final State indentedPredicateByLevel = shouldIndentFirstPropertyByLevel || shouldIndentOtherPropertyByLevel ? wrappedPredicate.write( indent( state.indentationLevel ) ) : wrappedPredicate; + final boolean shouldIndentFirstPropertyOnce = firstProperty && + ( inBrackets && state.indentationLevel > 1 ); + + final State indentedPredicate = shouldIndentFirstPropertyOnce ? + indentedPredicateByLevel.write( indent( 1 ) ) : indentedPredicateByLevel; + final State predicateAlignment = !firstProperty && style.alignPredicates && !subject.isAnon() ? indentedPredicate.write( " ".repeat( alignment ) ) : indentedPredicate; From b66fb836de2a80e89f18722a5aceda8ade09e484 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 9 Jul 2021 17:00:40 +0200 Subject: [PATCH 083/280] Fix flawed test --- .../java/de/atextor/turtle/formatter/TurtleFormatterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 2c0c63a3..7c135f80 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -362,7 +362,7 @@ public void testListWrappingAlways() { "foo2" "foo3" "foo4" - ) . + ) . """; assertThat( result.trim() ).isEqualTo( expected.trim() ); } From f66e5e19629c281e6d2abc7034fd5cba9a246d5b Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Jul 2021 05:56:59 +0200 Subject: [PATCH 084/280] Correctly space anonymous nodes in lists --- .../turtle/formatter/TurtleFormatter.java | 2 +- .../turtle/formatter/TurtleFormatterTest.java | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index ee79556d..9e48e3dc 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -366,7 +366,7 @@ private State writeListElement( final RDFNode element, final boolean firstElemen ( alignmentAfterElementIsWritten + 1 ) > style.maxLineLength; yield writeRdfNode( element, wouldElementExceedLineLength ? state.newLine().write( continuationIndent( state.indentationLevel ) ) : - ( firstElement ? state : state.write( " " ) ) ); + ( firstElement || state.getLastCharacter().equals( " " ) ? state : state.write( " " ) ) ); }; } diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 7c135f80..f9590541 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -395,6 +395,28 @@ public void testListWrappingForLongLines() { assertThat( result.trim() ).isEqualTo( expected.trim() ); } + @Test + public void testListOfAnonymousNodes() { + final String modelString = """ + @prefix : . + + :foo :bar ( [ + :x 1 ; + ] [ + :x 2 ; + ] ) . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + System.out.println( result ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + @Test public void testUtf8BomCharset() { final Model model = prefixModel(); From 63cdf4c3579b7d4451562bb649236c2619f7b1b1 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 21 Jul 2021 06:14:16 +0200 Subject: [PATCH 085/280] Use triple quotes for strings with linebreaks or quotes --- .../turtle/formatter/TurtleFormatter.java | 9 +++++--- .../turtle/formatter/TurtleFormatterTest.java | 21 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 9e48e3dc..c3eca1dd 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -402,11 +402,14 @@ private State writeUriResource( final Resource resource, final State state ) { } private State writeLiteral( final Literal literal, final State state ) { + final String quote = literal.getLexicalForm().contains( "\n" ) + || literal.getLexicalForm().contains( "\"" ) ? "\"\"\"" : "\""; + if ( literal.getDatatypeURI().equals( XSD.xboolean.getURI() ) ) { return state.write( literal.getBoolean() ? "true" : "false" ); } if ( literal.getDatatypeURI().equals( XSD.xstring.getURI() ) ) { - return state.write( "\"" + literal.getValue().toString() + "\"" ); + return state.write( quote + literal.getValue().toString() + quote ); } if ( literal.getDatatypeURI().equals( XSD.decimal.getURI() ) ) { return state.write( literal.getLexicalForm() ); @@ -418,11 +421,11 @@ private State writeLiteral( final Literal literal, final State state ) { return state.write( style.doubleFormat.format( literal.getDouble() ) ); } if ( literal.getDatatypeURI().equals( RDF.langString.getURI() ) ) { - return state.write( "\"" + literal.getLexicalForm() + "\"@" + literal.getLanguage() ); + return state.write( quote + literal.getLexicalForm() + quote + "@" + literal.getLanguage() ); } final Resource typeResource = ResourceFactory.createResource( literal.getDatatypeURI() ); - final State literalWritten = state.write( "\"" + literal.getLexicalForm() + "\"^^" ); + final State literalWritten = state.write( quote + literal.getLexicalForm() + quote + "^^" ); return writeUriResource( typeResource, literalWritten ); } diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index f9590541..b5b9000e 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -89,21 +89,26 @@ public void testLiterals() { @prefix xsd: . @prefix : . - :foo1 :bar 1 . + :foo01 :bar 1 . - :foo2 :bar "2" . + :foo02 :bar "2" . - :foo3 :bar true . + :foo03 :bar true . - :foo4 :bar -5.0 . + :foo04 :bar -5.0 . - :foo5 :bar 4.2E9 . + :foo05 :bar 4.2E9 . - :foo6 :bar "2021-01-01"^^xsd:date . + :foo06 :bar "2021-01-01"^^xsd:date . - :foo7 :bar "something"^^:custom . + :foo07 :bar "something"^^:custom . - :foo8 :bar "something"@en . + :foo08 :bar "something"@en . + + :foo09 :bar \"""This contains a " quote\""" . + + :foo10 :bar \"""This contains a + linebreak\""" . """; final Model model = modelFromString( modelString ); final FormattingStyle style = FormattingStyle.builder() From 5deade1286d4d98b3518d57b1c33066e80c3899b Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 22 Jul 2021 06:04:58 +0200 Subject: [PATCH 086/280] Escape strings in serialization, validate with property-based test --- build.gradle.kts | 1 + .../turtle/formatter/TurtleFormatter.java | 15 ++++--- .../TurtleFormatterPropertyTest.java | 40 +++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0df06dc8..c789476c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1") testImplementation("org.assertj:assertj-core:3.19.0") testImplementation("net.jqwik:jqwik:1.4.0") + testImplementation("org.apache.jena:apache-jena-libs:3.17.0") testAnnotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0") diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index c3eca1dd..8415df0f 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -402,14 +402,11 @@ private State writeUriResource( final Resource resource, final State state ) { } private State writeLiteral( final Literal literal, final State state ) { - final String quote = literal.getLexicalForm().contains( "\n" ) - || literal.getLexicalForm().contains( "\"" ) ? "\"\"\"" : "\""; - if ( literal.getDatatypeURI().equals( XSD.xboolean.getURI() ) ) { return state.write( literal.getBoolean() ? "true" : "false" ); } if ( literal.getDatatypeURI().equals( XSD.xstring.getURI() ) ) { - return state.write( quote + literal.getValue().toString() + quote ); + return state.write( quoteAndEscape( literal ) ); } if ( literal.getDatatypeURI().equals( XSD.decimal.getURI() ) ) { return state.write( literal.getLexicalForm() ); @@ -421,14 +418,20 @@ private State writeLiteral( final Literal literal, final State state ) { return state.write( style.doubleFormat.format( literal.getDouble() ) ); } if ( literal.getDatatypeURI().equals( RDF.langString.getURI() ) ) { - return state.write( quote + literal.getLexicalForm() + quote + "@" + literal.getLanguage() ); + return state.write( quoteAndEscape( literal ) + "@" + literal.getLanguage() ); } final Resource typeResource = ResourceFactory.createResource( literal.getDatatypeURI() ); - final State literalWritten = state.write( quote + literal.getLexicalForm() + quote + "^^" ); + final State literalWritten = state.write( quoteAndEscape( literal ) + "^^" ); return writeUriResource( typeResource, literalWritten ); } + private String quoteAndEscape( final RDFNode node ) { + final String value = node.asNode().getLiteralLexicalForm(); + final String quote = value.contains( "\n" ) || value.contains( "\"" ) ? "\"\"\"" : "\""; + return quote + value + quote; + } + private State writeRdfNode( final RDFNode node, final State state ) { if ( node.isResource() ) { return writeResource( node.asResource(), state ); diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index e6f693b8..3f72911d 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -15,10 +15,12 @@ import org.apache.jena.rdf.model.ResourceFactory; import org.apache.jena.rdf.model.Statement; +import java.io.ByteArrayOutputStream; import java.io.StringReader; import java.util.List; import java.util.function.Supplier; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.fail; public class TurtleFormatterPropertyTest { @@ -170,4 +172,42 @@ public void anyPrettyPrintedModelIsSyntacticallyValid( @ForAll( "anyModel" ) fin fail(); } } + + private final TurtleFormatter defaultFormatter = new TurtleFormatter( FormattingStyle.DEFAULT ); + + private final Resource subject = ResourceFactory.createResource( "urn:foo" ); + + private final org.apache.jena.rdf.model.Property predicate = ResourceFactory.createProperty( "urn:bar" ); + + @Provide + Arbitrary anyStringLiteralWithSpecialCharacters() { + return Arbitraries.strings().all().map( ResourceFactory::createStringLiteral ); + } + + @Property + public void anyModelContainingSpecialCharactersIsSyntacticallyValid( @ForAll( + "anyStringLiteralWithSpecialCharacters" ) final Literal literal ) { + final Model model = ModelFactory.createDefaultModel(); + model.add( subject, predicate, literal ); + + final ByteArrayOutputStream out = new ByteArrayOutputStream( 128 ); + try { + model.write( out, "TURTLE" ); + } catch ( final Exception e ) { + // If Jena itself can't write it, we don't need to try it + return; + } + + final String result = defaultFormatter.apply( model ); + final Model newModel = ModelFactory.createDefaultModel(); + try { + newModel.read( new StringReader( result ), "", "TURTLE" ); + final Literal newLiteral = + newModel.listStatements( subject, predicate, (RDFNode) null ).nextStatement().getLiteral(); + assertThat( newLiteral.asNode().getLiteralLexicalForm() ) + .isEqualTo( literal.asNode().getLiteralLexicalForm() ); + } catch ( final RuntimeException e ) { + fail(); + } + } } From b73e127511bc01a6924c4189b03763cacfb6fedb Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 22 Jul 2021 07:06:18 +0200 Subject: [PATCH 087/280] Use fixed seed for property-based test --- .../atextor/turtle/formatter/TurtleFormatterPropertyTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index 3f72911d..26545c8c 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -184,7 +184,7 @@ Arbitrary anyStringLiteralWithSpecialCharacters() { return Arbitraries.strings().all().map( ResourceFactory::createStringLiteral ); } - @Property + @Property( tries = 500, seed = "1" ) public void anyModelContainingSpecialCharactersIsSyntacticallyValid( @ForAll( "anyStringLiteralWithSpecialCharacters" ) final Literal literal ) { final Model model = ModelFactory.createDefaultModel(); @@ -207,7 +207,7 @@ public void anyModelContainingSpecialCharactersIsSyntacticallyValid( @ForAll( assertThat( newLiteral.asNode().getLiteralLexicalForm() ) .isEqualTo( literal.asNode().getLiteralLexicalForm() ); } catch ( final RuntimeException e ) { - fail(); + fail( e ); } } } From 8aece41be32b8426167533f1784f1de676637a05 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 26 Jul 2021 06:02:08 +0200 Subject: [PATCH 088/280] Update Gradle Wrapper --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f371643e..05679dc3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 29286b24d4f57123a0bf1e364bcf2ccc9d678e73 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 26 Jul 2021 06:02:22 +0200 Subject: [PATCH 089/280] Update dependency versions --- build.gradle.kts | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c789476c..5f10d16f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,8 +3,8 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask plugins { java jacoco - id("com.github.ben-manes.versions") version "0.36.0" - id("com.adarshr.test-logger") version "2.1.1" + id("com.github.ben-manes.versions") version "0.39.0" + id("com.adarshr.test-logger") version "3.0.0" id("io.franzbecker.gradle-lombok") version "4.0.0" `java-library` `maven-publish` @@ -19,20 +19,24 @@ repositories { } dependencies { - implementation("org.apache.jena:jena-core:3.17.0") - implementation("io.vavr:vavr:0.10.3") - implementation("org.slf4j:slf4j-api:1.7.30") + implementation("org.apache.jena:jena-core:4.1.0") + implementation("io.vavr:vavr:0.10.4") + implementation("org.slf4j:slf4j-api:1.7.32") + compileOnly("org.projectlombok:lombok:1.18.20") - annotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0") + annotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.4.1") + annotationProcessor("org.projectlombok:lombok:1.18.20") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1") - testImplementation("org.assertj:assertj-core:3.19.0") - testImplementation("net.jqwik:jqwik:1.4.0") - testImplementation("org.apache.jena:apache-jena-libs:3.17.0") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2") + testImplementation("org.assertj:assertj-core:3.20.2") + testImplementation("net.jqwik:jqwik:1.5.3") + testImplementation("org.apache.jena:apache-jena-libs:4.1.0") + testCompileOnly("org.projectlombok:lombok:1.18.20") - testAnnotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0") + testAnnotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.4.1") + testAnnotationProcessor("org.projectlombok:lombok:1.18.20") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.2") } java { @@ -54,7 +58,7 @@ tasks.named("dependencyUpdates", DependencyUpdatesTask::class.java).configure { } tasks.withType().configureEach { - options.compilerArgs.addAll(arrayOf("--release", "11")) + options.compilerArgs.addAll(arrayOf("--release", "11", "-Xlint:unchecked")) } tasks.compileJava { From d4094556be7738f7a506d2a479d991dd0beaf2f0 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 26 Jul 2021 06:02:40 +0200 Subject: [PATCH 090/280] Replace unchecked calls in test --- .../turtle/formatter/TurtleFormatterPropertyTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index 26545c8c..869dcf4d 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -72,8 +72,8 @@ Arbitrary anyIntegerNumberLiteral() { @Provide Arbitrary anyLiteral() { - return Arbitraries.oneOf( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), anyDoubleLiteral(), - anyIntegerNumberLiteral() ); + return Arbitraries.oneOf( List.of( anyStringLiteral(), anyLangStringLiteral(), anyFloatLiteral(), + anyDoubleLiteral(), anyIntegerNumberLiteral() ) ); } @Provide @@ -93,7 +93,7 @@ Arbitrary anyUrn() { @Provide Arbitrary anyUri() { - return Arbitraries.oneOf( anyUrl(), anyUrn() ); + return Arbitraries.oneOf( List.of( anyUrl(), anyUrn() ) ); } @Provide @@ -103,7 +103,7 @@ Arbitrary anyNamedResource() { @Provide Arbitrary anyResource() { - return Arbitraries.oneOf( anyAnonymousResource(), anyNamedResource() ); + return Arbitraries.oneOf( List.of( anyAnonymousResource(), anyNamedResource() ) ); } @Provide @@ -126,7 +126,7 @@ Arbitrary anyList( final Model model ) { @Provide Arbitrary anyRdfNode( final Model model ) { - return Arbitraries.oneOf( anyLiteral(), anyResource(), anyList( model ) ); + return Arbitraries.oneOf( List.of( anyLiteral(), anyResource(), anyList( model ) ) ); } @Provide From 2a181b520d58e06a48f763ebc60a628f09676f9f Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 26 Jul 2021 06:06:13 +0200 Subject: [PATCH 091/280] Update Readme --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5fb0639c..a74baf26 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.org) Model and produces as output a pretty-printed RDF/Turtle document. -Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. +Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The +current version is 1.2.0. **Current Status**: The library is feature-complete. @@ -115,13 +116,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.0 + 1.2.1 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.0'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.1'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.0")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.1")` ### Calling the formatter @@ -643,6 +644,10 @@ elements in RDF lists. ## Release Notes +* 1.2.1: + * Improve formatting for blank nodes nested in lists + * Use triple quotes for literals containing line breaks + * Use Jena's mechanisms for escaping special characters in literals * 1.2.0: * Add `wrapListItems` configuration option * Change license from LGPL 3.0 to Apache 2.0 From 07c5ba4fd928baf64ea584f591eaf62083ed36aa Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 26 Jul 2021 06:07:59 +0200 Subject: [PATCH 092/280] Release 1.2.1 Improve formatting and escaping of special characters From 42652e342d2ec30f0fdce80b2ff3d1e74c4e9576 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 26 Jul 2021 11:59:58 +0200 Subject: [PATCH 093/280] Fix current version in Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a74baf26..83529f2f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.0. +current version is 1.2.1. **Current Status**: The library is feature-complete. From f687a5ad4f1208b7fe9f04738859c95d4b844b7e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 14 Oct 2021 05:09:52 +0200 Subject: [PATCH 094/280] Update codecov-action to v2 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bbf11a64..4ee8ffa9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Gradle build run: ./gradlew clean build jacocoTestReport --stacktrace - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v2 with: name: codecov-umbrella env_vars: OS,USED_JAVA From 8b8565f07a8369cadeaa9f56712b46aab7798c61 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 3 Nov 2021 06:06:03 +0100 Subject: [PATCH 095/280] Update Gradle Wrapper --- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..7454180f2ae8848c63b8b4dea2cb829da983f2fa 100644 GIT binary patch delta 18435 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 B8dv}T delta 17845 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 X49Luk)baa85H9$5YCsTPT`SVRWMtMW diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 05679dc3..ffed3a25 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c..744e882e 100755 --- a/gradlew +++ b/gradlew @@ -72,7 +72,7 @@ case "`uname`" in Darwin* ) darwin=true ;; - MINGW* ) + MSYS* | MINGW* ) msys=true ;; NONSTOP* ) From 687448d3da60414c973597584d9ce1476974db06 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 4 Nov 2021 06:35:42 +0100 Subject: [PATCH 096/280] Fix property-based test to deal with broken unicode --- build.gradle.kts | 23 +++++++------------ .../TurtleFormatterPropertyTest.java | 6 ++++- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5f10d16f..89dffce6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,7 +24,6 @@ dependencies { implementation("org.slf4j:slf4j-api:1.7.32") compileOnly("org.projectlombok:lombok:1.18.20") - annotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.4.1") annotationProcessor("org.projectlombok:lombok:1.18.20") testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2") @@ -33,7 +32,6 @@ dependencies { testImplementation("org.apache.jena:apache-jena-libs:4.1.0") testCompileOnly("org.projectlombok:lombok:1.18.20") - testAnnotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.4.1") testAnnotationProcessor("org.projectlombok:lombok:1.18.20") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.2") @@ -57,20 +55,16 @@ tasks.named("dependencyUpdates", DependencyUpdatesTask::class.java).configure { } } -tasks.withType().configureEach { - options.compilerArgs.addAll(arrayOf("--release", "11", "-Xlint:unchecked")) -} - tasks.compileJava { options.encoding = "UTF-8" - sourceCompatibility = "15" - targetCompatibility = "11" + sourceCompatibility = "17" + targetCompatibility = "17" } tasks.compileTestJava { options.encoding = "UTF-8" - sourceCompatibility = "15" - targetCompatibility = "11" + sourceCompatibility = "17" + targetCompatibility = "17" } tasks.test { @@ -81,15 +75,14 @@ tasks.test { } jacoco { - toolVersion = "0.8.6" + toolVersion = "0.8.7" } tasks.jacocoTestReport { reports { - xml.isEnabled = true - xml.destination = file("${buildDir}/reports/jacoco/report.xml") - html.isEnabled = true - html.destination = file("${buildDir}/reports/jacoco/html-report") + xml.required.set(true) + html.required.set(true) + html.outputLocation.set(layout.buildDirectory.dir("reports/jacoco/html-report")) } } diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index 869dcf4d..5fcfc898 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -199,13 +199,17 @@ public void anyModelContainingSpecialCharactersIsSyntacticallyValid( @ForAll( } final String result = defaultFormatter.apply( model ); + final Model originalModel = ModelFactory.createDefaultModel(); final Model newModel = ModelFactory.createDefaultModel(); try { + originalModel.read( new StringReader( out.toString() ), "", "TURTLE" ); newModel.read( new StringReader( result ), "", "TURTLE" ); + final Literal originalLiteral = + originalModel.listStatements( subject, predicate, (RDFNode) null ).nextStatement().getLiteral(); final Literal newLiteral = newModel.listStatements( subject, predicate, (RDFNode) null ).nextStatement().getLiteral(); assertThat( newLiteral.asNode().getLiteralLexicalForm() ) - .isEqualTo( literal.asNode().getLiteralLexicalForm() ); + .isEqualTo( originalLiteral.asNode().getLiteralLexicalForm() ); } catch ( final RuntimeException e ) { fail( e ); } From 3855f169d3387b8f992ea17c51b6f3ba7a3354ea Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 4 Nov 2021 06:37:14 +0100 Subject: [PATCH 097/280] Update dependencies --- build.gradle.kts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 89dffce6..e4ede2bd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,8 +4,8 @@ plugins { java jacoco id("com.github.ben-manes.versions") version "0.39.0" - id("com.adarshr.test-logger") version "3.0.0" - id("io.franzbecker.gradle-lombok") version "4.0.0" + id("com.adarshr.test-logger") version "3.1.0" + id("io.franzbecker.gradle-lombok") version "5.0.0" `java-library` `maven-publish` signing @@ -19,22 +19,22 @@ repositories { } dependencies { - implementation("org.apache.jena:jena-core:4.1.0") + implementation("org.apache.jena:jena-core:4.2.0") implementation("io.vavr:vavr:0.10.4") implementation("org.slf4j:slf4j-api:1.7.32") - compileOnly("org.projectlombok:lombok:1.18.20") + compileOnly("org.projectlombok:lombok:1.18.22") - annotationProcessor("org.projectlombok:lombok:1.18.20") + annotationProcessor("org.projectlombok:lombok:1.18.22") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2") - testImplementation("org.assertj:assertj-core:3.20.2") - testImplementation("net.jqwik:jqwik:1.5.3") - testImplementation("org.apache.jena:apache-jena-libs:4.1.0") - testCompileOnly("org.projectlombok:lombok:1.18.20") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") + testImplementation("org.assertj:assertj-core:3.21.0") + testImplementation("net.jqwik:jqwik:1.5.6") + testImplementation("org.apache.jena:apache-jena-libs:4.2.0") + testCompileOnly("org.projectlombok:lombok:1.18.22") - testAnnotationProcessor("org.projectlombok:lombok:1.18.20") + testAnnotationProcessor("org.projectlombok:lombok:1.18.22") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.2") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") } java { From 5ce9db3d5ddc5b177478013d4682f6a8d634e4cc Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 4 Nov 2021 06:42:57 +0100 Subject: [PATCH 098/280] Update build setup to use JDK 17 --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ee8ffa9..520ffc55 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: timeout-minutes: 15 strategy: matrix: - java: [ 15 ] + java: [ 17 ] os: [ ubuntu, macos ] env: OS: ${{ matrix.os }} @@ -26,8 +26,9 @@ jobs: with: fetch-depth: 0 - name: Set up java - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: + distribution: 'temurin' java-version: ${{ matrix.java }} - name: Cache Gradle uses: actions/cache@v2 From 1bb34f8dd6c68d5fc5d100db992a26f165d2156e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 23 Nov 2021 05:21:47 +0100 Subject: [PATCH 099/280] Make KnownPrefix a record --- .../java/de/atextor/turtle/formatter/FormattingStyle.java | 7 +------ .../java/de/atextor/turtle/formatter/TurtleFormatter.java | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index ee8b452d..db0650eb 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -1,7 +1,6 @@ package de.atextor.turtle.formatter; import lombok.Builder; -import lombok.Value; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.RDFNode; import org.apache.jena.rdf.model.Resource; @@ -244,10 +243,6 @@ public enum WrappingStyle { NEVER } - @Value - public static class KnownPrefix { - String prefix; - - URI iri; + public record KnownPrefix(String prefix, URI iri) { } } diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 8415df0f..d7b1c7d7 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -210,8 +210,8 @@ private Set anonymousResourcesThatNeedAnId( final Model model ) { private PrefixMapping buildPrefixMapping( final Model model ) { final Map prefixMap = Stream.ofAll( style.knownPrefixes ) - .filter( knownPrefix -> model.getNsPrefixURI( knownPrefix.getPrefix() ) == null ) - .toMap( FormattingStyle.KnownPrefix::getPrefix, knownPrefix -> knownPrefix.getIri().toString() ); + .filter( knownPrefix -> model.getNsPrefixURI( knownPrefix.prefix() ) == null ) + .toMap( FormattingStyle.KnownPrefix::prefix, knownPrefix -> knownPrefix.iri().toString() ); return PrefixMapping.Factory.create().setNsPrefixes( model.getNsPrefixMap() ) .setNsPrefixes( prefixMap.toJavaMap() ); } From 042cbdcf2d13ba3ffec492df06f11ccaf6accc47 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 23 Nov 2021 05:22:51 +0100 Subject: [PATCH 100/280] Enable writing URIs with an empty base --- .../turtle/formatter/TurtleFormatter.java | 10 +++++++-- .../turtle/formatter/TurtleFormatterTest.java | 22 ++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index d7b1c7d7..9c4c8891 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -37,6 +37,8 @@ public class TurtleFormatter implements Function, BiConsumer" : shortForm; + // Workaround to force writing out URIs without a base that is "automatically determined" by Jena: + // when calling model.read(inputStream, base, language) and passing an empty String as base, Jena will + // replace that with something "smart" such as the current directory. + final String uriWithoutEmptyBase = uri.startsWith( EMPTY_BASE ) ? uri.substring( EMPTY_BASE.length() ) : uri; + final String shortForm = state.prefixMapping.shortForm( uriWithoutEmptyBase ); + return shortForm.equals( uriWithoutEmptyBase ) ? "<" + uriWithoutEmptyBase + ">" : shortForm; } private State writeUriResource( final Resource resource, final State state ) { diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index b5b9000e..0d1bd1a2 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -422,6 +422,26 @@ public void testListOfAnonymousNodes() { assertThat( result.trim() ).isEqualTo( modelString.trim() ); } + @Test + public void testEmptyUrlWithEmptyBase() { + final String modelString = """ + @prefix rdfs: . + @prefix : . + + :Person a rdfs:Class ; + :foo <> . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + System.out.println( result ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + @Test public void testUtf8BomCharset() { final Model model = prefixModel(); @@ -478,7 +498,7 @@ public void testSubjectsNotInSubjectOrder() { private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); - model.read( stream, "", "TURTLE" ); + model.read( stream, TurtleFormatter.EMPTY_BASE, "TURTLE" ); return model; } From 5e2fab1f706cda67549f4f991e6a33f765bd5d47 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 23 Nov 2021 05:27:43 +0100 Subject: [PATCH 101/280] Update Readme --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 83529f2f..3f358a70 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.1. +current version is 1.2.2. **Current Status**: The library is feature-complete. @@ -116,13 +116,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.1 + 1.2.2 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.1'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.2'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.1")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.2")` ### Calling the formatter @@ -644,6 +644,10 @@ elements in RDF lists. ## Release Notes +* 1.2.2: + * Enable writing URIs with an empty base: use `TurtleFormatter.EMPTY_BASE` as + value for "base" when reading a model using Jena's `model.read()` + * Update build to Java 17 * 1.2.1: * Improve formatting for blank nodes nested in lists * Use triple quotes for literals containing line breaks From 9aa0d483a703d4f27464f26e1026710e7a4ca9aa Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 23 Nov 2021 05:28:38 +0100 Subject: [PATCH 102/280] Release 1.2.2 Enable writing URIs with empty base and update to Java 17 From 22ebc7766e99e55abfc2f0a775c372f24b43a6ed Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 23 Nov 2021 05:37:29 +0100 Subject: [PATCH 103/280] Update Java version to 17 in release build --- .github/workflows/push-to-central.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push-to-central.yml b/.github/workflows/push-to-central.yml index f613913b..ec9c9bac 100644 --- a/.github/workflows/push-to-central.yml +++ b/.github/workflows/push-to-central.yml @@ -13,9 +13,10 @@ jobs: with: fetch-depth: 0 - name: Set up java - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: - java-version: 15 + distribution: 'temurin' + java-version: 17 - name: Cache Gradle uses: actions/cache@v2 with: From 587714d06299a6e3287e05e7bbac9f525e489525 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 23 Nov 2021 05:38:00 +0100 Subject: [PATCH 104/280] Release 1.2.2 Enable writing URIs with empty base and update to Java 17 From b6a5dc6a9b4d75cccfea2c7c76440d7e1cc3900d Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 14 Dec 2021 05:29:29 +0100 Subject: [PATCH 105/280] Add hint on usage as a CLI in README Fixes #1 --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f358a70..33dd906f 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,17 @@ the default style could look like this: ## Usage -### Add dependency +### Usage as a CLI (command line interface) + +turtle-formatter itself is only a library and thus intended to be used programmatically, which is +explained in the following sections. However, in the sibling project +[owl-cli](https://github.com/atextor/owl-cli), turtle-formatter is used and can be called using a +command line interface to pretty-print any OWL or RDF document. See owl-cli's [Getting +Started](https://atextor.de/owl-cli/main/snapshot/index.html) to get the tool and the [write command +documentation](https://atextor.de/owl-cli/main/snapshot/usage.html#write-command) to see which +command line switches are available to adjust the formatting. + +### Usage as a library Add the following dependency to your Maven `pom.xml`: ```xml From 11e062c54659f780f90704c1f4a2332b10118c6a Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 17 Jan 2022 06:02:50 +0100 Subject: [PATCH 106/280] Add test for handling URIs with escaped slashes Fixes #3 --- .../turtle/formatter/TurtleFormatterTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 0d1bd1a2..bcf86b61 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -15,6 +15,7 @@ import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; public class TurtleFormatterTest { @Test @@ -495,6 +496,21 @@ public void testSubjectsNotInSubjectOrder() { assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); } + @Test + public void testEscapedUri() { + final String modelString = """ + @prefix dc: . + @prefix doi: . + @prefix : . + @prefix rdfs: . + + :something a :publication ; + rdfs:label "Paper title" ; + dc:hasIdentifier doi:10.1137\\/1.9781611970937 . + """; + assertThatCode( () -> modelFromString( modelString ) ).doesNotThrowAnyException(); + } + private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); From e8fcb04294ea9804a5a90444e0ce7f581cfba276 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 21 Jan 2022 06:08:41 +0100 Subject: [PATCH 107/280] Escape reserved characters in local names ref #4 --- .../turtle/formatter/TurtleFormatter.java | 25 +++++++++++++++++- .../turtle/formatter/TurtleFormatterTest.java | 26 ++++++++++++------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 9c4c8891..f18b6ef5 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -32,6 +32,8 @@ import java.util.Comparator; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class TurtleFormatter implements Function, BiConsumer { @@ -41,6 +43,11 @@ public class TurtleFormatter implements Function, BiConsumer" : shortForm; + if ( shortForm.equals( uriWithoutEmptyBase ) ) { + // RDF Term: https://www.w3.org/TR/turtle/#grammar-production-IRIREF + return "<" + uriWithoutEmptyBase + ">"; + } else { + // Local name: https://www.w3.org/TR/turtle/#grammar-production-PN_LOCAL + return escapeLocalName( shortForm ); + } + } + + /** + * Perform escaping of reserved character escape sequences as described in https://www.w3.org/TR/turtle/#sec-escapes + * + * @param localName the local name of an RDF resources + * @return the escaped localName + */ + private String escapeLocalName( final String localName ) { + return RESERVED_CHARACTER_ESCAPE_SEQUENCES.matcher( localName ).replaceAll( match -> "\\\\" + match.group() ); } private State writeUriResource( final Resource resource, final State state ) { diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index bcf86b61..f3757f41 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -3,7 +3,10 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.ResourceFactory; +import org.apache.jena.rdf.model.Statement; import org.apache.jena.vocabulary.RDF; import org.junit.jupiter.api.Test; @@ -15,7 +18,6 @@ import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; public class TurtleFormatterTest { @Test @@ -497,18 +499,22 @@ public void testSubjectsNotInSubjectOrder() { } @Test - public void testEscapedUri() { + public void testEscapedLocalName() { final String modelString = """ - @prefix dc: . - @prefix doi: . - @prefix : . - @prefix rdfs: . + @prefix : . - :something a :publication ; - rdfs:label "Paper title" ; - dc:hasIdentifier doi:10.1137\\/1.9781611970937 . + :foo :something :ab\\/cd . """; - assertThatCode( () -> modelFromString( modelString ) ).doesNotThrowAnyException(); + final Model model = modelFromString( modelString ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = modelFromString( result ); + + final Resource foo = ResourceFactory.createResource( "http://example.com#foo" ); + final Statement fooStatement = resultModel.listStatements( foo, null, (RDFNode) null ).nextStatement(); + assertThat( fooStatement.getObject().asResource().getURI() ).isEqualTo( "http://example.com#ab/cd" ); } private Model modelFromString( final String content ) { From d4894d4a812caa33eeff4969a3332d98655b3796 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 21 Jan 2022 21:52:50 +0100 Subject: [PATCH 108/280] Escape special characters in literals ref #4 --- .../turtle/formatter/TurtleFormatter.java | 22 +++++++++++++++++-- .../turtle/formatter/TurtleFormatterTest.java | 19 +++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index f18b6ef5..6f4e3bb5 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -32,7 +32,6 @@ import java.util.Comparator; import java.util.function.BiConsumer; import java.util.function.Function; -import java.util.regex.Matcher; import java.util.regex.Pattern; public class TurtleFormatter implements Function, BiConsumer { @@ -48,6 +47,14 @@ public class TurtleFormatter implements Function, BiConsumer characterReplacements = HashMap.of( + "\t", "\\t", + "\b", "\\b", + "\r", "\\r", + "\f", "\\f", + "\"", quote.equals( "\"" ) ? "\\\"" : "\"", // Don't escape quotes in triple-quoted strings + "\\", "\\\\\\\\" + ); + + final String escapedValue = STRING_ESCAPE_SEQUENCES.matcher( value ).replaceAll( match -> + characterReplacements.getOrElse( match.group(), match.group() ) ); + return quote + escapedValue + quote; } private State writeRdfNode( final RDFNode node, final State state ) { diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index f3757f41..6d16870d 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -499,11 +499,14 @@ public void testSubjectsNotInSubjectOrder() { } @Test - public void testEscapedLocalName() { + public void testEscapedLocalNameAndEscapedString() { final String modelString = """ @prefix : . :foo :something :ab\\/cd . + :bar :something "ab\\\\cd" . + :baz :something "ab\\"cd" . + :baz2 :something \"""ab"cd\""" . """; final Model model = modelFromString( modelString ); final FormattingStyle style = FormattingStyle.builder().build(); @@ -512,9 +515,23 @@ public void testEscapedLocalName() { final String result = formatter.apply( model ); final Model resultModel = modelFromString( result ); + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + final Resource foo = ResourceFactory.createResource( "http://example.com#foo" ); final Statement fooStatement = resultModel.listStatements( foo, null, (RDFNode) null ).nextStatement(); assertThat( fooStatement.getObject().asResource().getURI() ).isEqualTo( "http://example.com#ab/cd" ); + + final Resource bar = ResourceFactory.createResource( "http://example.com#bar" ); + final Statement barStatement = resultModel.listStatements( bar, null, (RDFNode) null ).nextStatement(); + assertThat( barStatement.getObject().asLiteral().getString() ).isEqualTo( "ab\\cd" ); + + final Resource baz = ResourceFactory.createResource( "http://example.com#baz" ); + final Statement bazStatement = resultModel.listStatements( baz, null, (RDFNode) null ).nextStatement(); + assertThat( bazStatement.getObject().asLiteral().getString() ).isEqualTo( "ab\"cd" ); + + final Resource baz2 = ResourceFactory.createResource( "http://example.com#baz2" ); + final Statement baz2Statement = resultModel.listStatements( baz2, null, (RDFNode) null ).nextStatement(); + assertThat( baz2Statement.getObject().asLiteral().getString() ).isEqualTo( "ab\"cd" ); } private Model modelFromString( final String content ) { From 4ee2306e6b291f2c6f3a53718c756554479f427c Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 21 Jan 2022 21:57:48 +0100 Subject: [PATCH 109/280] Update Readme --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 33dd906f..75eba722 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.2. +current version is 1.2.3. **Current Status**: The library is feature-complete. @@ -126,13 +126,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.2 + 1.2.3 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.2'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.3'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.2")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.3")` ### Calling the formatter @@ -654,6 +654,8 @@ elements in RDF lists. ## Release Notes +* 1.2.3: + * Bugfix: Special characters in local names (curies) and literals are properly escaped * 1.2.2: * Enable writing URIs with an empty base: use `TurtleFormatter.EMPTY_BASE` as value for "base" when reading a model using Jena's `model.read()` From 9e31ab17a026b127676c5bacbc3f3ca20909e147 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 21 Jan 2022 21:58:25 +0100 Subject: [PATCH 110/280] Release 1.2.3 Properly escape special characters in local names and literals From 1252300ebd3ab5eb56ed550cef9aa5f0deeb2ba5 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 12 Sep 2022 07:17:24 +0200 Subject: [PATCH 111/280] Do not escape dashes in prefixes of local names Fixes #5 --- .../turtle/formatter/TurtleFormatter.java | 19 ++++++----- .../turtle/formatter/TurtleFormatterTest.java | 34 +++++++++++++++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 6f4e3bb5..45bb8fcc 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -198,8 +198,8 @@ private List determineStatements( final Model model, final Comparator } private State buildInitialState( final Model model, final OutputStream outputStream, - final PrefixMapping prefixMapping, - final Comparator predicateOrder ) { + final PrefixMapping prefixMapping, + final Comparator predicateOrder ) { return Stream .ofAll( anonymousResourcesThatNeedAnId( model ) ) .zipWithIndex() @@ -284,8 +284,8 @@ private String continuationIndent( final int level ) { } private State writeDelimiter( final String delimiter, final FormattingStyle.GapStyle before, - final FormattingStyle.GapStyle after, final String indentation, - final State state ) { + final FormattingStyle.GapStyle after, final String indentation, + final State state ) { final State beforeState = switch ( before ) { case SPACE -> state.lastCharacter.equals( " " ) ? state : state.write( " " ); case NOTHING -> state; @@ -305,7 +305,7 @@ private State writeComma( final State state ) { } private State writeSemicolon( final State state, final boolean omitLineBreak, - final boolean omitSpaceBeforeSemicolon, final String nextLineIndentation ) { + final boolean omitSpaceBeforeSemicolon, final String nextLineIndentation ) { final FormattingStyle.GapStyle beforeSemicolon = omitSpaceBeforeSemicolon ? FormattingStyle.GapStyle.NOTHING : style.beforeSemicolon; final FormattingStyle.GapStyle afterSemicolon = omitLineBreak ? FormattingStyle.GapStyle.NOTHING : @@ -419,7 +419,8 @@ private String uriResource( final Resource resource, final State state ) { return "<" + uriWithoutEmptyBase + ">"; } else { // Local name: https://www.w3.org/TR/turtle/#grammar-production-PN_LOCAL - return escapeLocalName( shortForm ); + final String[] prefixedName = shortForm.split( ":" ); + return prefixedName[0] + ":" + escapeLocalName( prefixedName[1] ); } } @@ -539,8 +540,8 @@ private State writeSubject( final Resource resource, final State state ) { } private State writeProperty( final Resource subject, final Property predicate, final boolean firstProperty, - final boolean lastProperty, final int alignment, - final String gapAfterPredicate, final State state ) { + final boolean lastProperty, final int alignment, + final String gapAfterPredicate, final State state ) { final Set objects = Stream.ofAll( () -> subject.listProperties( predicate ) ).map( Statement::getObject ).toSet(); @@ -641,7 +642,7 @@ private class State { public State( final OutputStream outputStream, final Model model, final Comparator predicateOrder, - final PrefixMapping prefixMapping ) { + final PrefixMapping prefixMapping ) { this( outputStream, model, HashSet.empty(), HashMap.empty(), predicateOrder, prefixMapping, 0, 0, "" ); } diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 6d16870d..a292871f 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -534,6 +534,40 @@ public void testEscapedLocalNameAndEscapedString() { assertThat( baz2Statement.getObject().asLiteral().getString() ).isEqualTo( "ab\"cd" ); } + @Test + public void testPrefixEscapeCharacters() { + final String modelString = """ + @prefix foo-bar: . + @prefix foo_bar: . + @prefix ä_1: . + + foo-bar:foo foo-bar:foo "value1" . + foo_bar:bar foo_bar:bar "value2" . + ä_1:baz ä_1:baz "value3" . + """; + final Model model = modelFromString( modelString ); + final FormattingStyle style = FormattingStyle.builder().build(); + + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + final Model resultModel = modelFromString( result ); + + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); + + final Resource subject1 = ResourceFactory.createResource( "http://example.com#foo" ); + final Statement subject1Statement = + resultModel.listStatements( subject1, null, (RDFNode) null ).nextStatement(); + assertThat( subject1Statement.getObject().asLiteral().getString() ).isEqualTo( "value1" ); + + final Resource subject2 = ResourceFactory.createResource( "http://example2.com#bar" ); + final Statement subject2Statement = resultModel.listStatements( subject2, null, (RDFNode) null ).nextStatement(); + assertThat( subject2Statement.getObject().asLiteral().getString() ).isEqualTo( "value2" ); + + final Resource subject3 = ResourceFactory.createResource( "http://example3.com#baz" ); + final Statement subject3Statement = resultModel.listStatements( subject3, null, (RDFNode) null ).nextStatement(); + assertThat( subject3Statement.getObject().asLiteral().getString() ).isEqualTo( "value3" ); + } + private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); From 6d5e03da9665edcc4c0b9b6714ac1b2d356a84c5 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 13 Sep 2022 04:49:40 +0200 Subject: [PATCH 112/280] Update Readme --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 75eba722..8c51c0f0 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.3. +current version is 1.2.4. **Current Status**: The library is feature-complete. @@ -126,13 +126,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.3 + 1.2.4 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.3'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.4'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.3")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.4")` ### Calling the formatter @@ -654,6 +654,8 @@ elements in RDF lists. ## Release Notes +* 1.2.4: + * Bugfix: Dashes in prefixes of local names are not escaped any more * 1.2.3: * Bugfix: Special characters in local names (curies) and literals are properly escaped * 1.2.2: From 86966e019a33775e4083f6bc9a83f54257aa885d Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 13 Sep 2022 04:53:09 +0200 Subject: [PATCH 113/280] Release 1.2.4 Dashes in prefixes of local names are not escaped any more From 50c3bbef4a462e291f098d49811ab0fc205b4047 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 20 Sep 2022 05:52:56 +0200 Subject: [PATCH 114/280] Do not escape dash, underscore and full stop in local names In the name part of local names (e.g., in "some:thing", the part after the colon) dash, underscore and full stop may be written either escaped or unescaped. For pretty printing/formatting however, it is preferrable to write them unescaped. --- .../turtle/formatter/TurtleFormatter.java | 6 +- .../turtle/formatter/TurtleFormatterTest.java | 65 ++++++++++++++----- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 45bb8fcc..5a76a56b 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -44,8 +44,12 @@ public class TurtleFormatter implements Function, BiConsumer . @prefix foo_bar: . @prefix ä_1: . + @prefix foo: . foo-bar:foo foo-bar:foo "value1" . foo_bar:bar foo_bar:bar "value2" . ä_1:baz ä_1:baz "value3" . + foo:some-thing foo:some-thing "x" . + foo:some.thing foo:some.thing "x" . + foo:some_thing foo:some_thing "x" . + foo:some\\*thing foo:some\\*thing "x" . + foo:some\\?thing foo:some\\?thing "x" . + foo:some\\#thing foo:some\\#thing "x" . + foo:some\\@thing foo:some\\@thing "x" . """; final Model model = modelFromString( modelString ); final FormattingStyle style = FormattingStyle.builder().build(); @@ -552,20 +561,42 @@ public void testPrefixEscapeCharacters() { final String result = formatter.apply( model ); final Model resultModel = modelFromString( result ); + // Should not be escaped: dashes and underscores in prefix part of local names + assertThat( result ).contains( "foo-bar:foo" ); + assertThat( result ).contains( "foo_bar:bar" ); + // Should not be escaped: dashes and underscores in name part of local names + assertThat( result ).contains( "foo:some-thing" ); + assertThat( result ).contains( "foo:some_thing" ); + // Should be escaped: other special characters in the name part of local names + assertThat( result ).contains( "foo:some\\*thing" ); + assertThat( result ).contains( "foo:some\\?thing" ); + assertThat( result ).contains( "foo:some\\#thing" ); + assertThat( result ).contains( "foo:some\\@thing" ); + assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); - final Resource subject1 = ResourceFactory.createResource( "http://example.com#foo" ); + final Resource subject1 = createResource( "http://example.com#foo" ); final Statement subject1Statement = resultModel.listStatements( subject1, null, (RDFNode) null ).nextStatement(); assertThat( subject1Statement.getObject().asLiteral().getString() ).isEqualTo( "value1" ); - final Resource subject2 = ResourceFactory.createResource( "http://example2.com#bar" ); - final Statement subject2Statement = resultModel.listStatements( subject2, null, (RDFNode) null ).nextStatement(); + final Resource subject2 = createResource( "http://example2.com#bar" ); + final Statement subject2Statement = resultModel.listStatements( subject2, null, (RDFNode) null ) + .nextStatement(); assertThat( subject2Statement.getObject().asLiteral().getString() ).isEqualTo( "value2" ); - final Resource subject3 = ResourceFactory.createResource( "http://example3.com#baz" ); - final Statement subject3Statement = resultModel.listStatements( subject3, null, (RDFNode) null ).nextStatement(); + final Resource subject3 = createResource( "http://example3.com#baz" ); + final Statement subject3Statement = resultModel.listStatements( subject3, null, (RDFNode) null ) + .nextStatement(); assertThat( subject3Statement.getObject().asLiteral().getString() ).isEqualTo( "value3" ); + + for ( final String namePart : + List.of( "some-thing", "some_thing", "some*thing", "some?thing", "some@thing", "some#thing" ) ) { + final Resource resource = createResource( "http://example4.com#" + namePart ); + final Statement statement = resultModel.listStatements( resource, null, (RDFNode) null ) + .nextStatement(); + assertThat( statement.getObject().asLiteral().getString() ).isEqualTo( "x" ); + } } private Model modelFromString( final String content ) { From 874be65d3285285f00eb6ba1394d78b8e24ba55e Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 20 Sep 2022 05:57:10 +0200 Subject: [PATCH 115/280] Update Readme --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8c51c0f0..886215f1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.4. +current version is 1.2.5. **Current Status**: The library is feature-complete. @@ -126,13 +126,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.4 + 1.2.5 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.4'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.5'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.4")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.5")` ### Calling the formatter @@ -654,6 +654,10 @@ elements in RDF lists. ## Release Notes +* 1.2.5: + * Dashes, underscores and full stops in the name part of local names are not + escaped any more. Technically not a bug fix since both is valid, but it's + nicer to read * 1.2.4: * Bugfix: Dashes in prefixes of local names are not escaped any more * 1.2.3: From ac5b9dc5cb14d028f3a9581260bf180606783a95 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 20 Sep 2022 06:00:36 +0200 Subject: [PATCH 116/280] Release 1.2.5 Do not escape dash, underscore and full stop in local names From 0536d0ae2a6faa497b94aaa03c8facc7e049ccba Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 4 Nov 2022 06:34:00 +0100 Subject: [PATCH 117/280] Remove vavr Remove vavr dependency --- build.gradle.kts | 1 - .../turtle/formatter/TurtleFormatter.java | 321 ++++++++++-------- 2 files changed, 171 insertions(+), 151 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e4ede2bd..cd26bdcc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,7 +20,6 @@ repositories { dependencies { implementation("org.apache.jena:jena-core:4.2.0") - implementation("io.vavr:vavr:0.10.4") implementation("org.slf4j:slf4j-api:1.7.32") compileOnly("org.projectlombok:lombok:1.18.22") diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 5a76a56b..0973fb6b 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -1,13 +1,5 @@ package de.atextor.turtle.formatter; -import io.vavr.Tuple2; -import io.vavr.collection.HashMap; -import io.vavr.collection.HashSet; -import io.vavr.collection.List; -import io.vavr.collection.Map; -import io.vavr.collection.Set; -import io.vavr.collection.Stream; -import io.vavr.control.Option; import lombok.AllArgsConstructor; import lombok.Value; import lombok.With; @@ -30,9 +22,17 @@ import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class TurtleFormatter implements Function, BiConsumer { @@ -44,7 +44,7 @@ public class TurtleFormatter implements Function, BiConsumer * Note that since the Turtle grammar rules allow dashes, underscores and full stops to be either escaped * or not escaped in the name part of local names, they are removed from the pattern string so that they * are printed unescaped. @@ -67,7 +67,7 @@ public class TurtleFormatter implements Function, BiConsumer> prefixOrder; + private final Comparator> prefixOrder; private final Comparator objectOrder; @@ -93,11 +93,11 @@ public TurtleFormatter( final FormattingStyle style ) { case UTF_16_LE -> StandardCharsets.UTF_16LE; }; - prefixOrder = Comparator.>comparingInt( entry -> - style.prefixOrder.contains( entry._1() ) ? - style.prefixOrder.indexOf( entry._1() ) : + prefixOrder = Comparator.>comparingInt( entry -> + style.prefixOrder.contains( entry.getKey() ) ? + style.prefixOrder.indexOf( entry.getKey() ) : Integer.MAX_VALUE - ).thenComparing( Tuple2::_1 ); + ).thenComparing( Map.Entry::getKey ); objectOrder = Comparator.comparingInt( object -> style.objectOrder.contains( object ) ? @@ -107,11 +107,11 @@ public TurtleFormatter( final FormattingStyle style ) { } private static List statements( final Model model ) { - return List.ofAll( model.listStatements().toList() ); + return model.listStatements().toList(); } private static List statements( final Model model, final Property predicate, final RDFNode object ) { - return List.ofAll( model.listStatements( null, predicate, object ).toList() ); + return model.listStatements( null, predicate, object ).toList(); } @Override @@ -161,55 +161,64 @@ public void accept( final Model model, final OutputStream outputStream ) { } private State writeAnonymousResources( final State state ) { - return List.ofAll( state.identifiedAnonymousResources.keySet() ) - .foldLeft( state, ( currentState, resource ) -> { - if ( !resource.listProperties().hasNext() ) { - return currentState; - } - return writeSubject( resource, currentState.withIndentationLevel( 0 ) ); - } ); + State s = state; + for ( final Resource r : state.identifiedAnonymousResources.keySet() ) { + if ( !r.listProperties().hasNext() ) { + continue; + } + s = writeSubject( r, s.withIndentationLevel( 0 ) ); + } + return s; } private State writeNamedResources( final State state, final List statements ) { - return statements - .map( Statement::getSubject ) - .foldLeft( state, ( currentState, resource ) -> { - if ( !resource.listProperties().hasNext() || currentState.visitedResources.contains( resource ) ) { - return currentState; - } - if ( resource.isURIResource() ) { - return writeSubject( resource, currentState.withIndentationLevel( 0 ) ); - } - final State resourceWritten = writeAnonymousResource( resource, currentState - .withIndentationLevel( 0 ) ); - final boolean omitSpaceBeforeDelimiter = !currentState.identifiedAnonymousResources.keySet() - .contains( resource ); - return writeDot( resourceWritten, omitSpaceBeforeDelimiter ).newLine(); - } ); + State currentState = state; + for ( final Statement statement : statements ) { + final Resource resource = statement.getSubject(); + if ( !resource.listProperties().hasNext() || currentState.visitedResources.contains( resource ) ) { + continue; + } + if ( resource.isURIResource() ) { + currentState = writeSubject( resource, currentState.withIndentationLevel( 0 ) ); + continue; + } + final State resourceWritten = writeAnonymousResource( resource, currentState + .withIndentationLevel( 0 ) ); + final boolean omitSpaceBeforeDelimiter = !currentState.identifiedAnonymousResources.keySet() + .contains( resource ); + currentState = writeDot( resourceWritten, omitSpaceBeforeDelimiter ).newLine(); + } + return currentState; } private List determineStatements( final Model model, final Comparator subjectComparator ) { - final List wellKnownSubjects = List.ofAll( style.subjectOrder ).flatMap( subjectType -> - statements( model, RDF.type, subjectType ).sorted( subjectComparator ) ); - final List otherSubjects = statements( model ) + final List wellKnownSubjects = style.subjectOrder.stream().flatMap( subjectType -> + statements( model, RDF.type, subjectType ).stream().sorted( subjectComparator ) ).toList(); + + final List otherSubjects = statements( model ).stream() .filter( statement -> !( statement.getPredicate().equals( RDF.type ) && statement.getObject().isResource() && style.subjectOrder.contains( statement.getObject().asResource() ) ) ) - .sorted( subjectComparator ); - return wellKnownSubjects.appendAll( otherSubjects ) + .sorted( subjectComparator ) + .toList(); + + return Stream.concat( wellKnownSubjects.stream(), otherSubjects.stream() ) .filter( statement -> !( statement.getSubject().isAnon() - && model.contains( null, null, statement.getSubject() ) ) ); + && model.contains( null, null, statement.getSubject() ) ) ) + .toList(); } private State buildInitialState( final Model model, final OutputStream outputStream, - final PrefixMapping prefixMapping, - final Comparator predicateOrder ) { - return Stream - .ofAll( anonymousResourcesThatNeedAnId( model ) ) - .zipWithIndex() - .map( entry -> new Tuple2<>( entry._1(), style.anonymousNodeIdGenerator.apply( entry._1(), entry._2() ) ) ) - .foldLeft( new State( outputStream, model, predicateOrder, prefixMapping ), ( state, entry ) -> - state.withIdentifiedAnonymousResource( entry._1(), entry._2() ) ); + final PrefixMapping prefixMapping, final Comparator predicateOrder ) { + + State currentState = new State( outputStream, model, predicateOrder, prefixMapping ); + int i = 0; + for ( final Resource r : anonymousResourcesThatNeedAnId( model ) ) { + final String s = style.anonymousNodeIdGenerator.apply( r, i ); + currentState = currentState.withIdentifiedAnonymousResource( r, s ); + i++; + } + return currentState; } /** @@ -220,25 +229,27 @@ private State buildInitialState( final Model model, final OutputStream outputStr * @return the set of anonymous resources that are referred to more than once */ private Set anonymousResourcesThatNeedAnId( final Model model ) { - return List.ofAll( model::listObjects ) + return model.listObjects().toList().stream() .filter( RDFNode::isResource ) .map( RDFNode::asResource ) .filter( RDFNode::isAnon ) - .filter( object -> statements( model, null, object ).toList().size() > 1 ) - .toSet(); + .filter( object -> statements( model, null, object ).size() > 1 ) + .collect( Collectors.toSet() ); } private PrefixMapping buildPrefixMapping( final Model model ) { - final Map prefixMap = Stream.ofAll( style.knownPrefixes ) + final Map prefixMap = style.knownPrefixes.stream() .filter( knownPrefix -> model.getNsPrefixURI( knownPrefix.prefix() ) == null ) - .toMap( FormattingStyle.KnownPrefix::prefix, knownPrefix -> knownPrefix.iri().toString() ); + .collect( Collectors.toMap( FormattingStyle.KnownPrefix::prefix, + knownPrefix -> knownPrefix.iri().toString() ) ); return PrefixMapping.Factory.create().setNsPrefixes( model.getNsPrefixMap() ) - .setNsPrefixes( prefixMap.toJavaMap() ); + .setNsPrefixes( prefixMap ); } private State writePrefixes( final State state ) { - final Map prefixes = HashMap.ofAll( state.prefixMapping.getNsPrefixMap() ); - final int maxPrefixLength = prefixes.keySet().map( String::length ).max().getOrElse( 0 ); + final Map prefixes = state.prefixMapping.getNsPrefixMap(); + final int maxPrefixLength = + prefixes.keySet().stream().map( String::length ).max( Integer::compareTo ).orElse( 0 ); final String prefixFormat = switch ( style.alignPrefixes ) { case OFF -> "@prefix %s: <%s>" + beforeDot + ".%n"; case LEFT -> "@prefix %-" + maxPrefixLength + "s: <%s>" + beforeDot + ".%n"; @@ -246,29 +257,35 @@ private State writePrefixes( final State state ) { }; final List urisInModel = allUsedUris( state.model ); - final State prefixesWritten = prefixes.toStream().sorted( prefixOrder ) - .filter( entry -> style.keepUnusedPrefixes || - urisInModel.find( resource -> resource.startsWith( entry._2() ) ).isDefined() ) - .foldLeft( state, ( newState, entry ) -> - newState.write( String.format( prefixFormat, entry._1(), entry._2() ) ) ); - return prefixesWritten.newLine(); + final List> entries = prefixes.entrySet().stream().sorted( prefixOrder ) + .filter( entry -> style.keepUnusedPrefixes || + urisInModel.stream().anyMatch( resource -> resource.startsWith( entry.getValue() ) ) ) + .toList(); + State currentState = state; + for ( final Map.Entry entry : entries ) { + currentState = currentState.write( String.format( prefixFormat, entry.getKey(), entry.getValue() ) ); + } + currentState = currentState.newLine(); + return currentState; } private List allUsedUris( final Model model ) { - return List.ofAll( model::listStatements ) - .flatMap( statement -> List.of( statement.getSubject(), statement.getPredicate(), statement.getObject() ) ) - .>map( rdfNode -> { + return model.listStatements().toList().stream() + .flatMap( statement -> Stream.of( statement.getSubject(), statement.getPredicate(), + statement.getObject() ) ) + .>map( rdfNode -> { if ( rdfNode.isURIResource() ) { - return Option.of( rdfNode.asResource().getURI() ); + return Optional.of( rdfNode.asResource().getURI() ); } if ( rdfNode.isLiteral() ) { - return Option.of( rdfNode.asLiteral().getDatatypeURI() ); + return Optional.of( rdfNode.asLiteral().getDatatypeURI() ); } - return Option.none(); + return Optional.empty(); } ) - .filter( Option::isDefined ) - .map( Option::get ); + .filter( Optional::isPresent ) + .map( Optional::get ) + .toList(); } private String indent( final int level ) { @@ -357,16 +374,17 @@ private State writeList( final Resource resource, final State state ) { final State opened = writeDelimiter( "(", style.beforeOpeningParenthesis, afterOpeningParenthesis, continuationIndent( state.indentationLevel ), state ); final java.util.List elementList = resource.as( RDFList.class ).asJavaList(); - final State elementsWritten = List.ofAll( elementList ).zipWithIndex() - .foldLeft( opened, ( currentState, indexedElement ) -> { - final RDFNode element = indexedElement._1(); - final int index = indexedElement._2(); - final boolean firstElement = index == 0; - return writeListElement( element, firstElement, currentState ); - } ); + + int index = 0; + State currentState = opened; + for ( final RDFNode element : elementList ) { + final boolean firstElement = index == 0; + currentState = writeListElement( element, firstElement, currentState ); + index++; + } final State finalLineBreakWritten = style.wrapListItems == FormattingStyle.WrappingStyle.ALWAYS ? - elementsWritten.newLine().write( indent( elementsWritten.indentationLevel ) ) : elementsWritten; + currentState.newLine().write( indent( currentState.indentationLevel ) ) : currentState; return writeDelimiter( ")", style.beforeClosingParenthesis, style.afterClosingParenthesis, continuationIndent( state.indentationLevel ), finalLineBreakWritten ); @@ -392,7 +410,7 @@ yield writeRdfNode( element, wouldElementExceedLineLength ? private State writeAnonymousResource( final Resource resource, final State state ) { if ( state.identifiedAnonymousResources.keySet().contains( resource ) ) { - return state.write( state.identifiedAnonymousResources.getOrElse( resource, "" ) ); + return state.write( state.identifiedAnonymousResources.getOrDefault( resource, "" ) ); } if ( !state.model.contains( resource, null, (RDFNode) null ) ) { @@ -470,7 +488,7 @@ private State writeLiteral( final Literal literal, final State state ) { private String quoteAndEscape( final RDFNode node ) { final String value = node.asNode().getLiteralLexicalForm(); final String quote = value.contains( "\n" ) || value.contains( "\"" ) ? "\"\"\"" : "\""; - final Map characterReplacements = HashMap.of( + final Map characterReplacements = Map.of( "\t", "\\t", "\b", "\\b", "\r", "\\r", @@ -480,7 +498,7 @@ private String quoteAndEscape( final RDFNode node ) { ); final String escapedValue = STRING_ESCAPE_SEQUENCES.matcher( value ).replaceAll( match -> - characterReplacements.getOrElse( match.group(), match.group() ) ); + characterReplacements.getOrDefault( match.group(), match.group() ) ); return quote + escapedValue + quote; } @@ -520,34 +538,31 @@ private State writeSubject( final Resource resource, final State state ) { final int predicateAlignment = style.firstPredicateInNewLine ? style.indentSize : gapAfterSubject.alignment; // predicates and objects - final Set properties = Stream.ofAll( resource::listProperties ) - .map( Statement::getPredicate ).toSet(); - - final int maxPropertyWidth = properties.map( property -> - uriResource( property, state ) ).map( String::length ).max().getOrElse( 0 ); - - return Stream - .ofAll( properties ) - .sorted( state.predicateOrder ) - .zipWithIndex() - .foldLeft( gapAfterSubject.addIndentationLevel(), ( currentState, indexedProperty ) -> { - final Property property = indexedProperty._1(); - final int index = indexedProperty._2(); - final boolean firstProperty = index == 0; - final boolean lastProperty = index == properties.size() - 1; - final int propertyWidth = uriResource( property, currentState ).length(); - final String gapAfterPredicate = style.alignObjects ? - " ".repeat( maxPropertyWidth - propertyWidth + 1 ) : " "; - return writeProperty( resource, property, firstProperty, lastProperty, predicateAlignment, - gapAfterPredicate, currentState ); - } ); + final Set properties = resource.listProperties().mapWith( Statement::getPredicate ).toSet(); + + final int maxPropertyWidth = properties.stream().map( property -> + uriResource( property, state ) ).map( String::length ).max( Integer::compareTo ).orElse( 0 ); + + int index = 0; + State currentState = gapAfterSubject.addIndentationLevel(); + for ( final Property property : properties.stream().sorted( state.predicateOrder ).toList() ) { + final boolean firstProperty = index == 0; + final boolean lastProperty = index == properties.size() - 1; + final int propertyWidth = uriResource( property, currentState ).length(); + final String gapAfterPredicate = style.alignObjects ? + " ".repeat( maxPropertyWidth - propertyWidth + 1 ) : " "; + currentState = writeProperty( resource, property, firstProperty, lastProperty, predicateAlignment, + gapAfterPredicate, currentState ); + index++; + } + return currentState; } private State writeProperty( final Resource subject, final Property predicate, final boolean firstProperty, final boolean lastProperty, final int alignment, final String gapAfterPredicate, final State state ) { final Set objects = - Stream.ofAll( () -> subject.listProperties( predicate ) ).map( Statement::getObject ).toSet(); + subject.listProperties( predicate ).mapWith( Statement::getObject ).toSet(); final boolean useComma = ( style.useCommaByDefault && !style.noCommaForPredicate.contains( predicate ) ) || ( !style.useCommaByDefault && style.commaForPredicate.contains( predicate ) ); @@ -579,47 +594,49 @@ private State writeProperty( final Resource subject, final Property predicate, f final State predicateWrittenOnce = useComma ? writeProperty( predicate, predicateAlignment ) .write( gapAfterPredicate ) : predicateAlignment; - return Stream - .ofAll( objects ) - .sorted( objectOrder ) - .zipWithIndex() - .foldLeft( predicateWrittenOnce, ( currentState, indexedObject ) -> { - final RDFNode object = indexedObject._1(); - final int index = indexedObject._2(); - final boolean lastObject = index == objects.size() - 1; - - final State predicateWritten = useComma ? currentState : - writeProperty( predicate, currentState ); - - final boolean isAnonWithBrackets = object.isAnon() - && !predicateWritten.identifiedAnonymousResources.keySet().contains( object.asResource() ); - final boolean isList = isList( object, predicateWritten ); - final State spaceWritten = !isAnonWithBrackets && !isList && !useComma ? - predicateWritten.write( gapAfterPredicate ) : - predicateWritten; - - final State objectWritten = writeRdfNode( object, spaceWritten ); - if ( useComma && !lastObject ) { - return writeComma( objectWritten ); - } + int index = 0; + State currentState = predicateWrittenOnce; + for ( final RDFNode object : objects.stream().sorted( objectOrder ).toList() ) { + final boolean lastObject = index == objects.size() - 1; + final State predicateWritten = useComma ? currentState : + writeProperty( predicate, currentState ); + + final boolean isAnonWithBrackets = object.isAnon() + && !predicateWritten.identifiedAnonymousResources.keySet().contains( object.asResource() ); + final boolean isList = isList( object, predicateWritten ); + final State spaceWritten = !isAnonWithBrackets && !isList && !useComma ? + predicateWritten.write( gapAfterPredicate ) : + predicateWritten; + + final State objectWritten = writeRdfNode( object, spaceWritten ); + if ( useComma && !lastObject ) { + currentState = writeComma( objectWritten ); + index++; + continue; + } - final boolean listWritten = isList && style.afterClosingParenthesis == FormattingStyle.GapStyle.NOTHING; - final boolean omitSpaceBeforeDelimiter = - object.isResource() - && object.isAnon() - && !listWritten - && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); - if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && !inBrackets ) { - return writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); - } - final String nextLineIndentation = - ( style.alignPredicates || ( subject.isAnon() ) ) - && !( !subject.isAnon() && !lastObject ) ? "" : - indent( objectWritten.indentationLevel ); - final State semicolonWritten = writeSemicolon( objectWritten, lastProperty && lastObject, - omitSpaceBeforeDelimiter, nextLineIndentation ); - return subject.isAnon() && lastProperty ? semicolonWritten.removeIndentationLevel() : semicolonWritten; - } ); + final boolean listWritten = isList && style.afterClosingParenthesis == FormattingStyle.GapStyle.NOTHING; + final boolean omitSpaceBeforeDelimiter = + object.isResource() + && object.isAnon() + && !listWritten + && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); + if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && !inBrackets ) { + currentState = writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); + index++; + continue; + } + final String nextLineIndentation = + ( style.alignPredicates || ( subject.isAnon() ) ) + && !( !subject.isAnon() && !lastObject ) ? "" : + indent( objectWritten.indentationLevel ); + final State semicolonWritten = writeSemicolon( objectWritten, lastProperty && lastObject, + omitSpaceBeforeDelimiter, nextLineIndentation ); + currentState = subject.isAnon() && lastProperty ? semicolonWritten.removeIndentationLevel() : + semicolonWritten; + index++; + } + return currentState; } @Value @@ -647,15 +664,19 @@ private class State { public State( final OutputStream outputStream, final Model model, final Comparator predicateOrder, final PrefixMapping prefixMapping ) { - this( outputStream, model, HashSet.empty(), HashMap.empty(), predicateOrder, prefixMapping, 0, 0, "" ); + this( outputStream, model, Set.of(), Map.of(), predicateOrder, prefixMapping, 0, 0, "" ); } public State withIdentifiedAnonymousResource( final Resource anonymousResource, final String id ) { - return withIdentifiedAnonymousResources( identifiedAnonymousResources.put( anonymousResource, id ) ); + final Map newMap = new HashMap<>( identifiedAnonymousResources ); + newMap.put( anonymousResource, id ); + return withIdentifiedAnonymousResources( newMap ); } public State withVisitedResource( final Resource visitedResource ) { - return withVisitedResources( visitedResources.add( visitedResource ) ); + final Set newSet = new HashSet<>( visitedResources ); + newSet.add( visitedResource ); + return withVisitedResources( newSet ); } public State addIndentationLevel() { From f1f70304a2cec47c507ce037b1a7af701e7e255f Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Mon, 21 Nov 2022 05:14:56 +0100 Subject: [PATCH 118/280] Remove code smells --- .../turtle/formatter/TurtleFormatter.java | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 0973fb6b..e90bc78d 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -161,14 +161,14 @@ public void accept( final Model model, final OutputStream outputStream ) { } private State writeAnonymousResources( final State state ) { - State s = state; - for ( final Resource r : state.identifiedAnonymousResources.keySet() ) { - if ( !r.listProperties().hasNext() ) { + State currentState = state; + for ( final Resource resource : state.identifiedAnonymousResources.keySet() ) { + if ( !resource.listProperties().hasNext() ) { continue; } - s = writeSubject( r, s.withIndentationLevel( 0 ) ); + currentState = writeSubject( resource, currentState.withIndentationLevel( 0 ) ); } - return s; + return currentState; } private State writeNamedResources( final State state, final List statements ) { @@ -182,27 +182,24 @@ private State writeNamedResources( final State state, final List stat currentState = writeSubject( resource, currentState.withIndentationLevel( 0 ) ); continue; } - final State resourceWritten = writeAnonymousResource( resource, currentState - .withIndentationLevel( 0 ) ); - final boolean omitSpaceBeforeDelimiter = !currentState.identifiedAnonymousResources.keySet() - .contains( resource ); + final State resourceWritten = writeAnonymousResource( resource, currentState.withIndentationLevel( 0 ) ); + final boolean omitSpaceBeforeDelimiter = !currentState.identifiedAnonymousResources.containsKey( resource ); currentState = writeDot( resourceWritten, omitSpaceBeforeDelimiter ).newLine(); } return currentState; } private List determineStatements( final Model model, final Comparator subjectComparator ) { - final List wellKnownSubjects = style.subjectOrder.stream().flatMap( subjectType -> - statements( model, RDF.type, subjectType ).stream().sorted( subjectComparator ) ).toList(); + final Stream wellKnownSubjects = style.subjectOrder.stream().flatMap( subjectType -> + statements( model, RDF.type, subjectType ).stream().sorted( subjectComparator ) ); - final List otherSubjects = statements( model ).stream() + final Stream otherSubjects = statements( model ).stream() .filter( statement -> !( statement.getPredicate().equals( RDF.type ) && statement.getObject().isResource() && style.subjectOrder.contains( statement.getObject().asResource() ) ) ) - .sorted( subjectComparator ) - .toList(); + .sorted( subjectComparator ); - return Stream.concat( wellKnownSubjects.stream(), otherSubjects.stream() ) + return Stream.concat( wellKnownSubjects, otherSubjects ) .filter( statement -> !( statement.getSubject().isAnon() && model.contains( null, null, statement.getSubject() ) ) ) .toList(); @@ -409,7 +406,7 @@ yield writeRdfNode( element, wouldElementExceedLineLength ? } private State writeAnonymousResource( final Resource resource, final State state ) { - if ( state.identifiedAnonymousResources.keySet().contains( resource ) ) { + if ( state.identifiedAnonymousResources.containsKey( resource ) ) { return state.write( state.identifiedAnonymousResources.getOrDefault( resource, "" ) ); } @@ -524,7 +521,7 @@ private State writeSubject( final Resource resource, final State state ) { } // indent - final boolean isIdentifiedAnon = state.identifiedAnonymousResources.keySet().contains( resource ); + final boolean isIdentifiedAnon = state.identifiedAnonymousResources.containsKey( resource ); final boolean subjectsNeedsIdentation = !resource.isAnon() || isIdentifiedAnon; final State indentedSubject = subjectsNeedsIdentation ? state.write( indent( state.indentationLevel ) ) : state; // subject @@ -570,7 +567,7 @@ private State writeProperty( final Resource subject, final Property predicate, f final State wrappedPredicate = firstProperty && style.firstPredicateInNewLine && !subject.isAnon() ? state.newLine() : state; - final boolean isNamedAnon = state.identifiedAnonymousResources.keySet().contains( subject ); + final boolean isNamedAnon = state.identifiedAnonymousResources.containsKey( subject ); final boolean inBrackets = subject.isAnon() && !isNamedAnon; final boolean shouldIndentFirstPropertyByLevel = firstProperty && @@ -602,7 +599,7 @@ private State writeProperty( final Resource subject, final Property predicate, f writeProperty( predicate, currentState ); final boolean isAnonWithBrackets = object.isAnon() - && !predicateWritten.identifiedAnonymousResources.keySet().contains( object.asResource() ); + && !predicateWritten.identifiedAnonymousResources.containsKey( object.asResource() ); final boolean isList = isList( object, predicateWritten ); final State spaceWritten = !isAnonWithBrackets && !isList && !useComma ? predicateWritten.write( gapAfterPredicate ) : @@ -620,7 +617,7 @@ private State writeProperty( final Resource subject, final Property predicate, f object.isResource() && object.isAnon() && !listWritten - && !currentState.identifiedAnonymousResources.keySet().contains( object.asResource() ); + && !currentState.identifiedAnonymousResources.containsKey( object.asResource() ); if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && !inBrackets ) { currentState = writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); index++; From 5910fac1d395b148c4614c45faab2ee221a76025 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 29 Nov 2022 06:03:01 +0100 Subject: [PATCH 119/280] Fix typo in property --- src/main/java/de/atextor/turtle/formatter/FormattingStyle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index db0650eb..3ab36094 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -141,7 +141,7 @@ public class FormattingStyle { public int continuationIndentSize = 4; @Builder.Default - public boolean indentPrediates = true; + public boolean indentPredicates = true; @Builder.Default public boolean insertFinalNewline = true; From 5714cdf40b49495a71403b94f87b57573488730c Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 29 Nov 2022 06:11:11 +0100 Subject: [PATCH 120/280] Fix alignment of repeated identical predicates --- .../turtle/formatter/TurtleFormatter.java | 14 +++++---- .../turtle/formatter/TurtleFormatterTest.java | 30 ++++++++++++++++--- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index e90bc78d..6759a5db 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -623,13 +623,17 @@ private State writeProperty( final Resource subject, final Property predicate, f index++; continue; } - final String nextLineIndentation = - ( style.alignPredicates || ( subject.isAnon() ) ) - && !( !subject.isAnon() && !lastObject ) ? "" : - indent( objectWritten.indentationLevel ); + final boolean doAlign = style.alignPredicates || subject.isAnon(); + final boolean moreIdenticalPredicatesRemaining = + subject.listProperties( predicate ).toList().size() > 1 && !lastObject; + final boolean isAnonOrLastObject = + ( subject.isAnon() || lastObject ) && !moreIdenticalPredicatesRemaining; + final String nextLineIndentation = doAlign && isAnonOrLastObject ? "" + : indent( objectWritten.indentationLevel ); final State semicolonWritten = writeSemicolon( objectWritten, lastProperty && lastObject, omitSpaceBeforeDelimiter, nextLineIndentation ); - currentState = subject.isAnon() && lastProperty ? semicolonWritten.removeIndentationLevel() : + currentState = subject.isAnon() && lastProperty && !moreIdenticalPredicatesRemaining ? + semicolonWritten.removeIndentationLevel() : semicolonWritten; index++; } diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 14a972b2..d699281b 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -484,10 +484,10 @@ public void testSubjectsNotInSubjectOrder() { :address a rdf:Property . :city a rdf:Property . :Max a :Person ; - :name "Max" ; - :address [ - :city "City Z" - ] . + :name "Max" ; + :address [ + :city "City Z" + ] . """; final Model model = modelFromString( modelString ); @@ -499,6 +499,28 @@ public void testSubjectsNotInSubjectOrder() { assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); } + @Test + public void testRepeatedPredicates() { + final String modelString = """ + @prefix : . + + :foo :bar [ + :something "x" ; + :something "y" ; + :something "z" ; + ] . + """; + final Model model = modelFromString( modelString ); + + final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + System.out.println( result ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + @Test public void testEscapedLocalNameAndEscapedString() { final String modelString = """ From 42d666d552cfe5a7be77e86f756df0f30b758a48 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 29 Nov 2022 06:13:45 +0100 Subject: [PATCH 121/280] Update Readme --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 886215f1..6a07beb9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.5. +current version is 1.2.6. **Current Status**: The library is feature-complete. @@ -126,11 +126,11 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.5 + 1.2.6 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.5'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.6'` Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.5")` @@ -654,6 +654,9 @@ elements in RDF lists. ## Release Notes +* 1.2.6: + * Fix typo in FormattingStyle property (`indentPredicates`) + * Fix alignment of repeated identical predicates * 1.2.5: * Dashes, underscores and full stops in the name part of local names are not escaped any more. Technically not a bug fix since both is valid, but it's From 47adb1ce83717f5e218136f0eba3f36ac2dbf71f Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 29 Nov 2022 06:15:00 +0100 Subject: [PATCH 122/280] Release 1.2.6 Fix alignment of repeated identical predicates From 56386abac2b0d88abafab24775da1d308a4bc627 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Tue, 29 Nov 2022 07:11:57 +0100 Subject: [PATCH 123/280] Fix version in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a07beb9..7b45381f 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ Add the following dependency to your Maven `pom.xml`: Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.6'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.5")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.6")` ### Calling the formatter From 9ad986b8f1a44804c0f74198e4ac4d27e1c85192 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 24 Mar 2023 05:55:18 +0100 Subject: [PATCH 124/280] Use Jena RIOT for URI and local name formatting Fixes #6 --- build.gradle.kts | 1 + .../turtle/formatter/TurtleFormatter.java | 149 +++++++++++++++--- .../turtle/formatter/TurtleFormatterTest.java | 22 +-- 3 files changed, 143 insertions(+), 29 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index cd26bdcc..6c66945c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,6 +20,7 @@ repositories { dependencies { implementation("org.apache.jena:jena-core:4.2.0") + implementation("org.apache.jena:jena-arq:4.2.0") implementation("org.slf4j:slf4j-api:1.7.32") compileOnly("org.projectlombok:lombok:1.18.22") diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 6759a5db..a9945d17 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -3,6 +3,9 @@ import lombok.AllArgsConstructor; import lombok.Value; import lombok.With; +import org.apache.jena.atlas.io.AWriter; +import org.apache.jena.atlas.lib.Pair; +import org.apache.jena.irix.IRIException; import org.apache.jena.rdf.model.Literal; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Property; @@ -11,6 +14,11 @@ import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.ResourceFactory; import org.apache.jena.rdf.model.Statement; +import org.apache.jena.riot.out.NodeFormatterTTL; +import org.apache.jena.riot.system.PrefixLib; +import org.apache.jena.riot.system.PrefixMap; +import org.apache.jena.riot.system.PrefixMapAdapter; +import org.apache.jena.riot.system.PrefixMapBase; import org.apache.jena.shared.PrefixMapping; import org.apache.jena.vocabulary.RDF; import org.apache.jena.vocabulary.XSD; @@ -43,19 +51,12 @@ public class TurtleFormatter implements Function, BiConsumerEscape Sequences. *

- * Note that since the Turtle grammar rules allow dashes, underscores and full stops to be either escaped - * or not escaped in the name part of local names, they are removed from the pattern string so that they - * are printed unescaped. - */ - private static final Pattern RESERVED_CHARACTER_ESCAPE_SEQUENCES = Pattern.compile( "[~\\!$&'()*+,;=/?#@%]" ); - - /** - * String escape sequences as described in https://www.w3.org/TR/turtle/#sec-escapes * Note that \n is not in the pattern, because it is serialized literally, in a triple-quoted string. * ' (single quote) is not in the pattern, because we never write single quoted strings and therefore don't * need to escape single quotes. + *

*/ private static final Pattern STRING_ESCAPE_SEQUENCES = Pattern.compile( "[\t\b\r\f\"\\\\]" ); @@ -434,23 +435,74 @@ private String uriResource( final Resource resource, final State state ) { final String uriWithoutEmptyBase = uri.startsWith( EMPTY_BASE ) ? uri.substring( EMPTY_BASE.length() ) : uri; final String shortForm = state.prefixMapping.shortForm( uriWithoutEmptyBase ); if ( shortForm.equals( uriWithoutEmptyBase ) ) { - // RDF Term: https://www.w3.org/TR/turtle/#grammar-production-IRIREF return "<" + uriWithoutEmptyBase + ">"; - } else { - // Local name: https://www.w3.org/TR/turtle/#grammar-production-PN_LOCAL - final String[] prefixedName = shortForm.split( ":" ); - return prefixedName[0] + ":" + escapeLocalName( prefixedName[1] ); } + // All other cases are delegated to Jena RIOT + final NodeFormatterTTL formatter = new NodeFormatterTTL( "", new CustomPrefixMap( state.prefixMapping ) ); + final NodeFormatterSink sink = new NodeFormatterSink(); + try { + formatter.formatURI( sink, uri ); + } catch ( final IRIException exception ) { + // The formatter encountered an invalid IRI. This should not have happend in the first place, i.e., + // it should not be present in the model. Since this should have been fixed by the parser, we handle + // it the same was as Jena Core: Still print it out. + return "<" + uri + ">"; + } + return sink.buffer.toString(); } /** - * Perform escaping of reserved character escape sequences as described in https://www.w3.org/TR/turtle/#sec-escapes - * - * @param localName the local name of an RDF resources - * @return the escaped localName + * Unfortunately, the logic in {@link PrefixMapAdapter#abbrev(String)} is broken and won't return a prefix + * even if one exists in the wrapped map; and the class is final, so we can't overwrite the method. */ - private String escapeLocalName( final String localName ) { - return RESERVED_CHARACTER_ESCAPE_SEQUENCES.matcher( localName ).replaceAll( match -> "\\\\" + match.group() ); + static class CustomPrefixMap extends PrefixMapBase implements PrefixMap { + private final PrefixMapping mapping; + + public CustomPrefixMap( final PrefixMapping mapping ) { + this.mapping = mapping; + } + + @Override + public String get( final String prefix ) { + return mapping.getNsPrefixURI( prefix ); + } + + @Override + public Map getMapping() { + return mapping.getNsPrefixMap(); + } + + @Override + public void add( final String prefix, final String iriString ) { + } + + @Override + public void delete( final String prefix ) { + } + + @Override + public void clear() { + } + + @Override + public boolean containsPrefix( final String prefix ) { + return mapping.getNsPrefixMap().containsKey( prefix ); + } + + @Override + public boolean isEmpty() { + return mapping.getNsPrefixMap().isEmpty(); + } + + @Override + public int size() { + return mapping.getNsPrefixMap().size(); + } + + @Override + public Pair abbrev( final String uriStr ) { + return PrefixLib.abbrev( this, uriStr ); + } } private State writeUriResource( final Resource resource, final State state ) { @@ -640,6 +692,63 @@ private State writeProperty( final Resource subject, final Property predicate, f return currentState; } + static class NodeFormatterSink implements AWriter { + StringBuffer buffer = new StringBuffer(); + + @Override + public void write( final char ch ) { + buffer.append( ch ); + } + + @Override + public void write( final char[] cbuf ) { + buffer.append( cbuf ); + } + + @Override + public void write( final String string ) { + buffer.append( string ); + } + + @Override + public void print( final char ch ) { + write( ch ); + } + + @Override + public void print( final char[] cbuf ) { + write( cbuf ); + } + + @Override + public void print( final String string ) { + write( string ); + } + + @Override + public void printf( final String fmt, final Object... arg ) { + write( String.format( fmt, arg ) ); + } + + @Override + public void println( final String object ) { + write( String.format( "%s%n", object ) ); + } + + @Override + public void println() { + write( String.format( "%n" ) ); + } + + @Override + public void flush() { + } + + @Override + public void close() { + } + } + @Value @With @AllArgsConstructor diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index d699281b..85359753 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -573,8 +573,10 @@ public void testPrefixEscapeCharacters() { foo:some_thing foo:some_thing "x" . foo:some\\*thing foo:some\\*thing "x" . foo:some\\?thing foo:some\\?thing "x" . - foo:some\\#thing foo:some\\#thing "x" . foo:some\\@thing foo:some\\@thing "x" . + foo:something "x" . + foo::another foo:test "x" . + foo:\\$10 foo:test "x" . """; final Model model = modelFromString( modelString ); final FormattingStyle style = FormattingStyle.builder().build(); @@ -583,17 +585,19 @@ public void testPrefixEscapeCharacters() { final String result = formatter.apply( model ); final Model resultModel = modelFromString( result ); - // Should not be escaped: dashes and underscores in prefix part of local names + // Should not be escaped and should be local names: dashes and underscores in prefix part of local names assertThat( result ).contains( "foo-bar:foo" ); assertThat( result ).contains( "foo_bar:bar" ); - // Should not be escaped: dashes and underscores in name part of local names + assertThat( result ).contains( "foo::another" ); + // Should not be escaped and should be local names: dashes and underscores in name part of local names assertThat( result ).contains( "foo:some-thing" ); assertThat( result ).contains( "foo:some_thing" ); - // Should be escaped: other special characters in the name part of local names - assertThat( result ).contains( "foo:some\\*thing" ); - assertThat( result ).contains( "foo:some\\?thing" ); - assertThat( result ).contains( "foo:some\\#thing" ); - assertThat( result ).contains( "foo:some\\@thing" ); + // Should be full URIs, since local names would be invalid + assertThat( result ).contains( "http://example4.com#some*thing" ); + assertThat( result ).contains( "http://example4.com#some?thing" ); + assertThat( result ).contains( "http://example4.com#some@thing" ); + assertThat( result ).contains( "http://example4.com#-10" ); + assertThat( result ).contains( "http://example4.com#$10" ); assertThat( model.isIsomorphicWith( resultModel ) ).isTrue(); @@ -613,7 +617,7 @@ public void testPrefixEscapeCharacters() { assertThat( subject3Statement.getObject().asLiteral().getString() ).isEqualTo( "value3" ); for ( final String namePart : - List.of( "some-thing", "some_thing", "some*thing", "some?thing", "some@thing", "some#thing" ) ) { + List.of( "some-thing", "some_thing", "some*thing", "some?thing", "some@thing" ) ) { final Resource resource = createResource( "http://example4.com#" + namePart ); final Statement statement = resultModel.listStatements( resource, null, (RDFNode) null ) .nextStatement(); From f8dfdc94f0aaae8e7ff56b5fee69051429b31c07 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 24 Mar 2023 05:59:35 +0100 Subject: [PATCH 125/280] Update dependencies --- build.gradle.kts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6c66945c..85ceb216 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,8 +3,8 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask plugins { java jacoco - id("com.github.ben-manes.versions") version "0.39.0" - id("com.adarshr.test-logger") version "3.1.0" + id("com.github.ben-manes.versions") version "0.46.0" + id("com.adarshr.test-logger") version "3.2.0" id("io.franzbecker.gradle-lombok") version "5.0.0" `java-library` `maven-publish` @@ -19,22 +19,22 @@ repositories { } dependencies { - implementation("org.apache.jena:jena-core:4.2.0") - implementation("org.apache.jena:jena-arq:4.2.0") - implementation("org.slf4j:slf4j-api:1.7.32") - compileOnly("org.projectlombok:lombok:1.18.22") + implementation("org.apache.jena:jena-core:4.7.0") + implementation("org.apache.jena:jena-arq:4.7.0") + implementation("org.slf4j:slf4j-api:2.0.7") + compileOnly("org.projectlombok:lombok:1.18.26") - annotationProcessor("org.projectlombok:lombok:1.18.22") + annotationProcessor("org.projectlombok:lombok:1.18.26") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") - testImplementation("org.assertj:assertj-core:3.21.0") - testImplementation("net.jqwik:jqwik:1.5.6") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2") + testImplementation("org.assertj:assertj-core:3.24.2") + testImplementation("net.jqwik:jqwik:1.7.3") testImplementation("org.apache.jena:apache-jena-libs:4.2.0") - testCompileOnly("org.projectlombok:lombok:1.18.22") + testCompileOnly("org.projectlombok:lombok:1.18.26") - testAnnotationProcessor("org.projectlombok:lombok:1.18.22") + testAnnotationProcessor("org.projectlombok:lombok:1.18.26") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") } java { From eff77ef5aea6976b137df2afbb5e58bd47ceea1a Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 24 Mar 2023 06:02:36 +0100 Subject: [PATCH 126/280] Update readme --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7b45381f..4c1c19a4 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.6. +current version is 1.2.7. **Current Status**: The library is feature-complete. @@ -126,13 +126,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.6 + 1.2.7 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.6'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.7'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.6")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.7")` ### Calling the formatter @@ -654,6 +654,9 @@ elements in RDF lists. ## Release Notes +* 1.2.7: + * Bugfix: URIs and local names are formatted using Jena RIOT; no invalid local + names are printed any longer * 1.2.6: * Fix typo in FormattingStyle property (`indentPredicates`) * Fix alignment of repeated identical predicates From 23ec1e7544ebf68b05d5ecedab3a95e7d9fb2573 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 24 Mar 2023 06:03:03 +0100 Subject: [PATCH 127/280] Release 1.2.7 Use Jena RIOT for formatting URIs and local names From ae42abb31c9375420aa475db6e5e7a05fe8dadc5 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 9 Aug 2023 06:07:19 +0200 Subject: [PATCH 128/280] Fix escaping of quotes as last characters in triple-quoted strings --- .../turtle/formatter/FormattingStyle.java | 9 ++++ .../turtle/formatter/TurtleFormatter.java | 29 +++++++++---- .../TurtleFormatterPropertyTest.java | 9 ++-- .../turtle/formatter/TurtleFormatterTest.java | 41 ++++++++++++++++++- 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index 3ab36094..caac7400 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -107,6 +107,9 @@ public class FormattingStyle { @Builder.Default public IndentStyle indentStyle = IndentStyle.SPACE; + @Builder.Default + public QuoteStyle quoteStyle = QuoteStyle.TRIPLE_QUOTES_FOR_MULTILINE; + @Builder.Default public WrappingStyle wrapListItems = WrappingStyle.FOR_LONG_LINES; @@ -243,6 +246,12 @@ public enum WrappingStyle { NEVER } + public enum QuoteStyle { + ALWAYS_SINGE_QUOTES, + TRIPLE_QUOTES_FOR_MULTILINE, + ALWAYS_TRIPLE_QUOTES + } + public record KnownPrefix(String prefix, URI iri) { } } diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index a9945d17..014662a5 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -53,12 +53,11 @@ public class TurtleFormatter implements Function, BiConsumerEscape Sequences. *

- * Note that \n is not in the pattern, because it is serialized literally, in a triple-quoted string. * ' (single quote) is not in the pattern, because we never write single quoted strings and therefore don't * need to escape single quotes. *

*/ - private static final Pattern STRING_ESCAPE_SEQUENCES = Pattern.compile( "[\t\b\r\f\"\\\\]" ); + private static final Pattern STRING_ESCAPE_SEQUENCES = Pattern.compile( "[\t\b\n\r\f\"\\\\]" ); private final FormattingStyle style; @@ -536,19 +535,31 @@ private State writeLiteral( final Literal literal, final State state ) { private String quoteAndEscape( final RDFNode node ) { final String value = node.asNode().getLiteralLexicalForm(); - final String quote = value.contains( "\n" ) || value.contains( "\"" ) ? "\"\"\"" : "\""; + final String quote = switch ( style.quoteStyle ) { + case ALWAYS_SINGE_QUOTES -> "\""; + case ALWAYS_TRIPLE_QUOTES -> "\"\"\""; + case TRIPLE_QUOTES_FOR_MULTILINE -> value.contains( "\n" ) ? "\"\"\"" : "\""; + }; + final Map characterReplacements = Map.of( - "\t", "\\t", - "\b", "\\b", - "\r", "\\r", - "\f", "\\f", - "\"", quote.equals( "\"" ) ? "\\\"" : "\"", // Don't escape quotes in triple-quoted strings + "\t", "\\\\t", + "\b", "\\\\b", + "\r", "\\\\r", + "\f", "\\\\f", + "\n", quote.equals( "\"" ) ? "\\\\n" : "\n", // Don't escape line breaks in triple-quoted strings + "\"", quote.equals( "\"" ) ? "\\\\\"" : "\"", // Don't escape quotes in triple-quoted strings "\\", "\\\\\\\\" ); final String escapedValue = STRING_ESCAPE_SEQUENCES.matcher( value ).replaceAll( match -> characterReplacements.getOrDefault( match.group(), match.group() ) ); - return quote + escapedValue + quote; + + // Special case: If the last character in the triple-quoted string is a quote, it must be escaped + // See https://github.com/atextor/turtle-formatter/issues/9 + final String result = quote.equals( "\"\"\"" ) && escapedValue.endsWith( "\"" ) + ? escapedValue.substring( 0, escapedValue.length() - 1 ) + "\\\"" + : escapedValue; + return quote + result + quote; } private State writeRdfNode( final RDFNode node, final State state ) { diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java index 5fcfc898..fcaa3907 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterPropertyTest.java @@ -26,7 +26,7 @@ public class TurtleFormatterPropertyTest { @Provide Arbitrary anyString() { - return Arbitraries.strings().ofMaxLength( 5 ); + return Arbitraries.strings().all().ofMaxLength( 5 ); } @Provide @@ -64,9 +64,12 @@ Arbitrary anyIntegerNumberLiteral() { return Arbitraries.of( ResourceFactory.createTypedLiteral( "1", XSDDatatype.XSDint ), ResourceFactory.createTypedLiteral( "2", XSDDatatype.XSDlong ), - ResourceFactory.createTypedLiteral( "3", XSDDatatype.XSDbyte ), + ResourceFactory.createTypedLiteral( "3", XSDDatatype.XSDshort ), ResourceFactory.createTypedLiteral( "4", XSDDatatype.XSDbyte ), - ResourceFactory.createTypedLiteral( "5", XSDDatatype.XSDunsignedByte ) + ResourceFactory.createTypedLiteral( "5", XSDDatatype.XSDunsignedByte ), + ResourceFactory.createTypedLiteral( "6", XSDDatatype.XSDunsignedInt ), + ResourceFactory.createTypedLiteral( "7", XSDDatatype.XSDunsignedLong ), + ResourceFactory.createTypedLiteral( "8", XSDDatatype.XSDunsignedShort ) ); } diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 85359753..48b467ef 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -109,13 +109,52 @@ public void testLiterals() { :foo08 :bar "something"@en . - :foo09 :bar \"""This contains a " quote\""" . + :foo09 :bar "This contains a \\" quote" . :foo10 :bar \"""This contains a linebreak\""" . """; final Model model = modelFromString( modelString ); final FormattingStyle style = FormattingStyle.builder() + .knownPrefixes( Set.of() ) + .quoteStyle( FormattingStyle.QuoteStyle.TRIPLE_QUOTES_FOR_MULTILINE ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @Test + public void testQuotedStringsWithSingleQuotes() { + final String modelString = """ + @prefix : . + + :foo :bar "This contains and ends with a \\"quote\\"" ; + :bar2 "This contains a\\nlinebreak" ; + :bar3 "This contains \\t \\\\ \\b" . + """; + final Model model = modelFromString( modelString ); + final FormattingStyle style = FormattingStyle.builder() + .quoteStyle( FormattingStyle.QuoteStyle.ALWAYS_SINGE_QUOTES ) + .knownPrefixes( Set.of() ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + final String result = formatter.apply( model ); + assertThat( result.trim() ).isEqualTo( modelString.trim() ); + } + + @SuppressWarnings( "TextBlockMigration" ) + @Test + public void testQuotedStringsWithTripleQuotes() { + // We'll put this in a regular string instead of a text block to make the escaping and the + // RDF triple quotes inside the string clearer + final String modelString = "@prefix : .\n" + + "\n" + + ":foo :bar \"\"\"This contains and ends with a \"quote\\\"\"\"\" ;\n" + + " :bar2 \"\"\"This contains \\t \\\\ \\b\"\"\" .\n"; + final Model model = modelFromString( modelString ); + final FormattingStyle style = FormattingStyle.builder() + .quoteStyle( FormattingStyle.QuoteStyle.ALWAYS_TRIPLE_QUOTES ) .knownPrefixes( Set.of() ) .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); From f9d9161415d607100ed6ea3e5b207bea162d2c73 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 9 Aug 2023 06:13:32 +0200 Subject: [PATCH 129/280] Update Readme --- README.md | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4c1c19a4..3cd47053 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.7. +current version is 1.2.8. **Current Status**: The library is feature-complete. @@ -126,13 +126,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.7 + 1.2.8 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.7'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.8'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.7")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.8")` ### Calling the formatter @@ -327,7 +327,25 @@ automatically treated as `false`. + + + +`quoteStyle` + + + + +`ALWAYS_SINGLE_QUOTES`, `TRIPLE_QUOTES_FOR_MULTILINE` or `ALWAYS_TRIPLE_QUOTES`. +Determines which quotes should be used for literals. Triple-quoted strings can +contain literal quotes and line breaks. + + + +`TRIPLE_QUOTES_FOR_MULTILINE` + + + @@ -654,6 +672,10 @@ elements in RDF lists. ## Release Notes +* 1.2.8: + * Bugfix: Quotes that are the last character in a triple-quoted string are + escaped correctly + * New style switch: `FormattingStyle.quoteStyle` * 1.2.7: * Bugfix: URIs and local names are formatted using Jena RIOT; no invalid local names are printed any longer From 6ab3e9afba80a5aa0736b114b49af3042bd811a4 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 9 Aug 2023 06:14:43 +0200 Subject: [PATCH 130/280] Release 1.2.8 Fix escaping in triple-quoted strings and introduce quote style From be72d125e720556bf70ece02d36b50ab28e527e1 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 22 Sep 2023 05:44:48 +0200 Subject: [PATCH 131/280] Change default dummy base URI to pass Jena's URI validation --- src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 014662a5..1b587cd7 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -46,7 +46,7 @@ public class TurtleFormatter implements Function, BiConsumer Date: Fri, 22 Sep 2023 05:45:27 +0200 Subject: [PATCH 132/280] Make dummy base URI configurable in formatting style --- src/main/java/de/atextor/turtle/formatter/FormattingStyle.java | 3 +++ src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java | 3 ++- .../java/de/atextor/turtle/formatter/TurtleFormatterTest.java | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java index caac7400..e319fe08 100644 --- a/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java +++ b/src/main/java/de/atextor/turtle/formatter/FormattingStyle.java @@ -50,6 +50,9 @@ public class FormattingStyle { PREFIX_DCTERMS ); + @Builder.Default + public String emptyRdfBase = TurtleFormatter.DEFAULT_EMPTY_BASE; + @Builder.Default public GapStyle afterClosingParenthesis = GapStyle.NOTHING; diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 1b587cd7..4253ce39 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -431,7 +431,8 @@ private String uriResource( final Resource resource, final State state ) { // Workaround to force writing out URIs without a base that is "automatically determined" by Jena: // when calling model.read(inputStream, base, language) and passing an empty String as base, Jena will // replace that with something "smart" such as the current directory. - final String uriWithoutEmptyBase = uri.startsWith( EMPTY_BASE ) ? uri.substring( EMPTY_BASE.length() ) : uri; + final String uriWithoutEmptyBase = uri.startsWith( style.emptyRdfBase ) ? + uri.substring( style.emptyRdfBase.length() ) : uri; final String shortForm = state.prefixMapping.shortForm( uriWithoutEmptyBase ); if ( shortForm.equals( uriWithoutEmptyBase ) ) { return "<" + uriWithoutEmptyBase + ">"; diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 48b467ef..338df142 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -667,7 +667,7 @@ public void testPrefixEscapeCharacters() { private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); - model.read( stream, TurtleFormatter.EMPTY_BASE, "TURTLE" ); + model.read( stream, TurtleFormatter.DEFAULT_EMPTY_BASE, "TURTLE" ); return model; } From 22f86c45fc2c7cc69268ed87deebf469c7478b7f Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 22 Sep 2023 05:46:10 +0200 Subject: [PATCH 133/280] Update dependencies to latest versions --- build.gradle.kts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 85ceb216..48ad70e3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask plugins { java jacoco - id("com.github.ben-manes.versions") version "0.46.0" + id("com.github.ben-manes.versions") version "0.48.0" id("com.adarshr.test-logger") version "3.2.0" id("io.franzbecker.gradle-lombok") version "5.0.0" `java-library` @@ -19,22 +19,22 @@ repositories { } dependencies { - implementation("org.apache.jena:jena-core:4.7.0") - implementation("org.apache.jena:jena-arq:4.7.0") - implementation("org.slf4j:slf4j-api:2.0.7") - compileOnly("org.projectlombok:lombok:1.18.26") + implementation("org.apache.jena:jena-core:4.9.0") + implementation("org.apache.jena:jena-arq:4.9.0") + implementation("org.slf4j:slf4j-api:2.0.9") + compileOnly("org.projectlombok:lombok:1.18.30") - annotationProcessor("org.projectlombok:lombok:1.18.26") + annotationProcessor("org.projectlombok:lombok:1.18.30") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0") testImplementation("org.assertj:assertj-core:3.24.2") - testImplementation("net.jqwik:jqwik:1.7.3") - testImplementation("org.apache.jena:apache-jena-libs:4.2.0") - testCompileOnly("org.projectlombok:lombok:1.18.26") + testImplementation("net.jqwik:jqwik:1.8.0") + testImplementation("org.apache.jena:apache-jena-libs:4.9.0") + testCompileOnly("org.projectlombok:lombok:1.18.30") - testAnnotationProcessor("org.projectlombok:lombok:1.18.26") + testAnnotationProcessor("org.projectlombok:lombok:1.18.30") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0") } java { From aa6d29e5efe771d83d50c67abd481743974da2ce Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 22 Sep 2023 06:02:25 +0200 Subject: [PATCH 134/280] Update Readme --- README.md | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3cd47053..855f93f7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.8. +current version is 1.2.9. **Current Status**: The library is feature-complete. @@ -126,27 +126,32 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.8 + 1.2.9 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.8'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.9'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.8")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.9")` ### Calling the formatter ```java +import java.io.FileInputStream; import de.atextor.turtle.formatter.FormattingStyle; import de.atextor.turtle.formatter.TurtleFormatter; import org.apache.jena.rdf.model.Model; -import org.apache.jena.riot.RDFDataMgr; +import org.apache.jena.rdf.model.ModelFactory; // ... -TurtleFormatter formatter = new TurtleFormatter(FormattingStyle.DEFAULT); -// Build or load a Jena Model -Model model = RDFDataMgr.loadModel("data.ttl"); +// Determine formatting style +FormattingStyle style = FormattingStyle.DEFAULT; +TurtleFormatter formatter = new TurtleFormatter(style); +// Build or load a Jena Model. +// Use the style's base URI for loading the model. +Model model = ModelFactory.createDefaultModel(); +model.read(new FileInputStream("data.ttl"), style.emptyRdfBase, "TURTLE"); // Either create a string... String prettyPrintedModel = formatter.apply(model); // ...or write directly to an OutputStream @@ -173,6 +178,21 @@ The following options can be set on the FormattingStyle builder: +`emptyRdfBase` + + +Set the URI that should be left out in formatting. If you don't care about +this, don't change it and use the FormattingStyle's emptyRdfBase field as the +base URI when loading/creating the model that will be formatted, see [calling +the formatter](#calling-the-formatter). + + +urn:turtleformatter:internal + + + + + `alignPrefixes` @@ -672,6 +692,9 @@ elements in RDF lists. ## Release Notes +* 1.2.9: + * The dummy base URI is now configurable in the formatting style. Its default + value was changed (to `urn:turtleformatter:internal`) to make it a valid URI. * 1.2.8: * Bugfix: Quotes that are the last character in a triple-quoted string are escaped correctly From 14fa4f3076d86c46833dafbb5539f25f2ca34d2a Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 22 Sep 2023 06:06:59 +0200 Subject: [PATCH 135/280] Remove linke break in markdown link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 855f93f7..3cb8eed3 100644 --- a/README.md +++ b/README.md @@ -183,8 +183,8 @@ The following options can be set on the FormattingStyle builder: Set the URI that should be left out in formatting. If you don't care about this, don't change it and use the FormattingStyle's emptyRdfBase field as the -base URI when loading/creating the model that will be formatted, see [calling -the formatter](#calling-the-formatter). +base URI when loading/creating the model that will be formatted, see +[calling the formatter](#calling-the-formatter). urn:turtleformatter:internal From 18f271d8e4e61f15e68009ab8bc8398123a6b0b0 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 22 Sep 2023 06:07:53 +0200 Subject: [PATCH 136/280] Make link URL absolute --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3cb8eed3..958dea7d 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ The following options can be set on the FormattingStyle builder: Set the URI that should be left out in formatting. If you don't care about this, don't change it and use the FormattingStyle's emptyRdfBase field as the base URI when loading/creating the model that will be formatted, see -[calling the formatter](#calling-the-formatter). +[calling the formatter](https://github.com/atextor/turtle-formatter#calling-the-formatter). urn:turtleformatter:internal From 4304524a2946d4a118d64f8d4c4b90a63b069fe8 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 22 Sep 2023 06:08:52 +0200 Subject: [PATCH 137/280] Use HTML link instead of markdown in table --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 958dea7d..7c3aa17f 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ The following options can be set on the FormattingStyle builder: Set the URI that should be left out in formatting. If you don't care about this, don't change it and use the FormattingStyle's emptyRdfBase field as the base URI when loading/creating the model that will be formatted, see -[calling the formatter](https://github.com/atextor/turtle-formatter#calling-the-formatter). +calling the formatter. urn:turtleformatter:internal From 1bd36b49fc19fbd688eaf0c6f96f463285446d13 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 22 Sep 2023 06:09:58 +0200 Subject: [PATCH 138/280] Release 1.2.9 Make empty base URI configurable in formatting style From 45189b0025c1dbd6a1175155ee7539dd71e09ed6 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 3 Nov 2023 05:17:33 +0100 Subject: [PATCH 139/280] Honor endOfLine style when formatting prefixes Fixes #10 --- .../turtle/formatter/TurtleFormatter.java | 12 ++--- .../turtle/formatter/TurtleFormatterTest.java | 47 ++++++++++++++++--- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java index 4253ce39..b5016c65 100644 --- a/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java +++ b/src/main/java/de/atextor/turtle/formatter/TurtleFormatter.java @@ -248,9 +248,9 @@ private State writePrefixes( final State state ) { final int maxPrefixLength = prefixes.keySet().stream().map( String::length ).max( Integer::compareTo ).orElse( 0 ); final String prefixFormat = switch ( style.alignPrefixes ) { - case OFF -> "@prefix %s: <%s>" + beforeDot + ".%n"; - case LEFT -> "@prefix %-" + maxPrefixLength + "s: <%s>" + beforeDot + ".%n"; - case RIGHT -> "@prefix %" + maxPrefixLength + "s: <%s>" + beforeDot + ".%n"; + case OFF -> "@prefix %s: <%s>" + beforeDot + "." + endOfLine; + case LEFT -> "@prefix %-" + maxPrefixLength + "s: <%s>" + beforeDot + "." + endOfLine; + case RIGHT -> "@prefix %" + maxPrefixLength + "s: <%s>" + beforeDot + "." + endOfLine; }; final List urisInModel = allUsedUris( state.model ); @@ -704,7 +704,7 @@ private State writeProperty( final Resource subject, final Property predicate, f return currentState; } - static class NodeFormatterSink implements AWriter { + class NodeFormatterSink implements AWriter { StringBuffer buffer = new StringBuffer(); @Override @@ -744,12 +744,12 @@ public void printf( final String fmt, final Object... arg ) { @Override public void println( final String object ) { - write( String.format( "%s%n", object ) ); + write( object + endOfLine ); } @Override public void println() { - write( String.format( "%n" ) ); + write( endOfLine ); } @Override diff --git a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java index 338df142..11bc0ddd 100644 --- a/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java +++ b/src/test/java/de/atextor/turtle/formatter/TurtleFormatterTest.java @@ -14,6 +14,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Map; import java.util.Set; import static org.apache.jena.rdf.model.ResourceFactory.createProperty; @@ -149,9 +150,8 @@ public void testQuotedStringsWithTripleQuotes() { // We'll put this in a regular string instead of a text block to make the escaping and the // RDF triple quotes inside the string clearer final String modelString = "@prefix : .\n" + - "\n" + - ":foo :bar \"\"\"This contains and ends with a \"quote\\\"\"\"\" ;\n" + - " :bar2 \"\"\"This contains \\t \\\\ \\b\"\"\" .\n"; + "\n:foo :bar \"\"\"This contains and ends with a \"quote\\\"\"\"\" ;\n" + + " :bar2 \"\"\"This contains \\t \\\\ \\b\"\"\" .\n"; final Model model = modelFromString( modelString ); final FormattingStyle style = FormattingStyle.builder() .quoteStyle( FormattingStyle.QuoteStyle.ALWAYS_TRIPLE_QUOTES ) @@ -461,7 +461,6 @@ public void testListOfAnonymousNodes() { .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); - System.out.println( result ); assertThat( result.trim() ).isEqualTo( modelString.trim() ); } @@ -481,7 +480,6 @@ public void testEmptyUrlWithEmptyBase() { .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); - System.out.println( result ); assertThat( result.trim() ).isEqualTo( modelString.trim() ); } @@ -556,7 +554,6 @@ public void testRepeatedPredicates() { .build(); final TurtleFormatter formatter = new TurtleFormatter( style ); final String result = formatter.apply( model ); - System.out.println( result ); assertThat( result.trim() ).isEqualTo( modelString.trim() ); } @@ -664,6 +661,44 @@ public void testPrefixEscapeCharacters() { } } + @Test + void testRespectEndOfLineConfig() { + final Map expected = Map.of( + FormattingStyle.EndOfLineStyle.LF, "\n", + FormattingStyle.EndOfLineStyle.CR, "\r", + FormattingStyle.EndOfLineStyle.CRLF, "\r\n" ); + final Map> unexpected = Map.of( + FormattingStyle.EndOfLineStyle.LF, List.of( "\r", "\r\n" ), + FormattingStyle.EndOfLineStyle.CR, List.of( "\n", "\r\n" ), + FormattingStyle.EndOfLineStyle.CRLF, List.of() ); + + for ( final FormattingStyle.EndOfLineStyle endOfLine : FormattingStyle.EndOfLineStyle.values() ) { + final FormattingStyle style = FormattingStyle.builder() + .endOfLine( endOfLine ) + .build(); + final TurtleFormatter formatter = new TurtleFormatter( style ); + + final String expectedLineEnding = expected.get( endOfLine ); + final List unexpectedLineEndings = unexpected.get( endOfLine ); + + final Model onlyPrefixesModel = prefixModel(); + final String onlyPrefixesResult = formatter.apply( onlyPrefixesModel ); + assertThat( onlyPrefixesResult ).contains( expectedLineEnding ); + unexpectedLineEndings.forEach( unexpectedLineEnding -> assertThat( onlyPrefixesResult ).doesNotContain( unexpectedLineEnding ) ); + + final Model modelWithAssertions = modelFromString( """ + @prefix rdfs: . + @prefix : . + + :Person a rdfs:Class ; + :foo <> . + """ ); + final String modelWithAssertionsResult = formatter.apply( modelWithAssertions ); + assertThat( modelWithAssertionsResult ).contains( expectedLineEnding ); + unexpectedLineEndings.forEach( unexpectedLineEnding -> assertThat( modelWithAssertionsResult ).doesNotContain( unexpectedLineEnding ) ); + } + } + private Model modelFromString( final String content ) { final Model model = ModelFactory.createDefaultModel(); final InputStream stream = new ByteArrayInputStream( content.getBytes( StandardCharsets.UTF_8 ) ); From c3677db250d20245a676426252d9c8414b545de6 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 3 Nov 2023 05:20:11 +0100 Subject: [PATCH 140/280] Update Readme --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7c3aa17f..20835c34 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It takes as input a formatting style and an [Apache Jena](https://jena.apache.or produces as output a pretty-printed RDF/Turtle document. Starting from version 1.2.0, turtle-formatter is licensed under Apache 2.0. The -current version is 1.2.9. +current version is 1.2.10. **Current Status**: The library is feature-complete. @@ -126,13 +126,13 @@ Add the following dependency to your Maven `pom.xml`: de.atextor turtle-formatter - 1.2.9 + 1.2.10 ``` -Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.9'` +Gradle/Groovy: `implementation 'de.atextor:turtle-formatter:1.2.10'` -Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.9")` +Gradle/Kotlin: `implementation("de.atextor:turtle-formatter:1.2.10")` ### Calling the formatter @@ -692,6 +692,8 @@ elements in RDF lists. ## Release Notes +* 1.2.10: + * Configured endOfLine style is honored in prefix formatting * 1.2.9: * The dummy base URI is now configurable in the formatting style. Its default value was changed (to `urn:turtleformatter:internal`) to make it a valid URI. From fe32acef1b675b5933636a2934214c8c42ef8eb0 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 3 Nov 2023 05:22:11 +0100 Subject: [PATCH 141/280] Release 1.2.10 Configured endOfLine style is honored in prefix formatting From c2c91e88b06d9d2077bfac84fcab07bee2f4d289 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 8 Nov 2023 05:05:33 +0100 Subject: [PATCH 142/280] Add Maven build output to .gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 820d767f..12c24471 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,8 @@ docs/modules/ROOT/assets/images/*.svg **/src/generated/java -*/lombok.config \ No newline at end of file +*/lombok.config + +**/.flattened-pom.xml + +*/target \ No newline at end of file From b11ff2f1dc6106febff04363549a28925ea27f60 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 8 Nov 2023 05:24:12 +0100 Subject: [PATCH 143/280] Add root pom --- pom.xml | 478 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 pom.xml diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..f26443d8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,478 @@ + + + 4.0.0 + + de.atextor.ret + ret + 1.0-SNAPSHOT + pom + + RDF Engineering Toolkit + https://github.com/atextor/ret + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Andreas Textor + mail@atextor.de + + + + + scm:git:https://github.com/atextor/ret.git + scm:git:https://github.com/atextor/ret.git + https://github.com/atextor/ret/tree/main + + + + + UTF-8 + 17 + 17 + + + 2.9.2 + 4.8.162 + 1.16.0 + 2.15.0 + 1.10.0 + 23.0.1 + 32.1.2-jre + 4.5.14 + 2.15.2 + 4.9.0 + 1.4.11 + 1.18.30 + 2.6.5 + 5.5.0 + 4.7.5 + 2.0.9 + 1.2.10 + 0.10.4 + + + 3.24.2 + 5.10.0 + 1.8.0 + + + 1.4.1 + 0.8.9 + 3.8.1 + 3.0.1 + 3.3.2 + 3.2.1 + 1.2.1 + 3.0.0-M7 + 1.6.8 + + + + ret-diagram-owl + ret-infer + ret-write + ret-cli + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + + de.atextor.ret + ret-diagram-owl + ${project.version} + + + de.atextor.ret + ret-infer + ${project.version} + + + de.atextor.ret + ret-write + ${project.version} + + + + + com.github.ben-manes.caffeine + caffeine + ${caffeine-version} + + + io.github.classgraph + classgraph + ${classgraph-version} + + + commons-codec + commons-codec + ${commons-codec-version} + + + commons-io + commons-io + ${commons-io-version} + + + org.apache.commons + commons-text + ${commons-text-version} + + + com.google.guava + guava + ${guava-version} + + + org.apache.httpcomponents + httpclient + ${httpclient-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind-version} + + + org.apache.jena + jena + ${jena-version} + pom + + + org.apache.jena + jena-arq + ${jena-version} + + + org.apache.jena + jena-core + ${jena-version} + + + org.apache.jena + apache-jena-libs + ${jena-version} + pom + + + ch.qos.logback + logback-classic + ${logback-version} + + + org.projectlombok + lombok + ${lombok-version} + + + com.github.galigator.openllet + openllet-jena + ${openllet-version} + + + net.sourceforge.owlapi + owlapi-distribution + ${owlapi-version} + + + info.picocli + picocli + ${picocli-version} + + + org.slf4j + slf4j-api + ${slf4j-api-version} + + + org.graalvm.nativeimage + svm + ${graalvm-version} + + + de.atextor + turtle-formatter + ${turtle-formatter-version} + + + io.vavr + vavr + ${vavr-version} + + + + + org.assertj + assertj-core + ${assertj-version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter-version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter-version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter-version} + test + + + net.jqwik + jqwik + ${jqwik-version} + test + + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin-version} + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin-version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin-version} + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin-version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin-version} + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin-version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin-version} + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${nexus-staging-maven-plugin-version} + + + + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin-version} + + + ossrh + + + + flatten + process-resources + + flatten + + + + clean-flatten + clean + + clean + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin-version} + + + default-prepare-agent + + prepare-agent + + + ${project.build.directory}/jacoco.exec + + + + create-report + + report + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin-version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + org.projectlombok + lombok + ${lombok-version} + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin-version} + + + attach-javadocs + + jar + + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin-version} + + + attach-sources + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin-version} + + + me.fabriciorby + maven-surefire-junit5-tree-reporter + ${maven-surefire-junit5-tree-reporter-version} + + + + false + ${project.build.directory}/${testreports.surefire} + + **/*Tests.java + **/*Test.java + + plain + + true + + + UNICODE + true + true + true + true + false + true + true + false + + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin-version} + + + sign-artifacts + verify + + sign + + + + + + --pinentry-mode + loopback + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${nexus-staging-maven-plugin-version} + true + + ossrh + https://oss.sonatype.org/ + true + + + + + + + From 486ebf55dc521f14373696f22f286df45c037fa8 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 8 Nov 2023 05:30:19 +0100 Subject: [PATCH 144/280] Turn write module to Maven module --- ret-write/pom.xml | 77 +++++++++++++++++++ .../de/atextor/ret}/write/Configuration.java | 5 +- .../java/de/atextor/ret}/write/RdfWriter.java | 4 +- .../de/atextor/ret}/write/RdfWriterTest.java | 2 +- write/build.gradle | 64 --------------- 5 files changed, 83 insertions(+), 69 deletions(-) create mode 100644 ret-write/pom.xml rename {write/src/main/java/de/atextor/owlcli => ret-write/src/main/java/de/atextor/ret}/write/Configuration.java (92%) rename {write/src/main/java/de/atextor/owlcli => ret-write/src/main/java/de/atextor/ret}/write/RdfWriter.java (96%) rename {write/src/test/java/de/atextor/owlcli => ret-write/src/test/java/de/atextor/ret}/write/RdfWriterTest.java (99%) delete mode 100644 write/build.gradle diff --git a/ret-write/pom.xml b/ret-write/pom.xml new file mode 100644 index 00000000..8bf3ea88 --- /dev/null +++ b/ret-write/pom.xml @@ -0,0 +1,77 @@ + + + + ret + de.atextor.ret + 1.0-SNAPSHOT + + 4.0.0 + + ret-write + + + 17 + 17 + UTF-8 + + + + + + org.apache.jena + jena + pom + + + org.apache.jena + jena-core + + + org.apache.jena + jena-arq + + + org.slf4j + slf4j-api + + + de.atextor + turtle-formatter + + + io.vavr + vavr + + + + + org.projectlombok + lombok + compile + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + net.jqwik + jqwik + test + + + \ No newline at end of file diff --git a/write/src/main/java/de/atextor/owlcli/write/Configuration.java b/ret-write/src/main/java/de/atextor/ret/write/Configuration.java similarity index 92% rename from write/src/main/java/de/atextor/owlcli/write/Configuration.java rename to ret-write/src/main/java/de/atextor/ret/write/Configuration.java index 67f145ab..a69bf7dc 100644 --- a/write/src/main/java/de/atextor/owlcli/write/Configuration.java +++ b/ret-write/src/main/java/de/atextor/ret/write/Configuration.java @@ -14,17 +14,18 @@ * limitations under the License. */ -package de.atextor.owlcli.write; +package de.atextor.ret.write; import de.atextor.turtle.formatter.FormattingStyle; -import de.atextor.turtle.formatter.TurtleFormatter; import lombok.Builder; @Builder public class Configuration { + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public Format outputFormat = Format.TURTLE; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public Format inputFormat = Format.TURTLE; diff --git a/write/src/main/java/de/atextor/owlcli/write/RdfWriter.java b/ret-write/src/main/java/de/atextor/ret/write/RdfWriter.java similarity index 96% rename from write/src/main/java/de/atextor/owlcli/write/RdfWriter.java rename to ret-write/src/main/java/de/atextor/ret/write/RdfWriter.java index 2900a6ae..e828441b 100644 --- a/write/src/main/java/de/atextor/owlcli/write/RdfWriter.java +++ b/ret-write/src/main/java/de/atextor/ret/write/RdfWriter.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.write; +package de.atextor.ret.write; import de.atextor.turtle.formatter.FormattingStyle; import de.atextor.turtle.formatter.TurtleFormatter; @@ -82,7 +82,7 @@ public Try writeTurtle( final Model model, final OutputStream output, fina } /** - * Builds a RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} + * Builds an RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} * * @param format the format * @return the format identifier for the Jena parser diff --git a/write/src/test/java/de/atextor/owlcli/write/RdfWriterTest.java b/ret-write/src/test/java/de/atextor/ret/write/RdfWriterTest.java similarity index 99% rename from write/src/test/java/de/atextor/owlcli/write/RdfWriterTest.java rename to ret-write/src/test/java/de/atextor/ret/write/RdfWriterTest.java index 7a68b4ca..3fe6429b 100644 --- a/write/src/test/java/de/atextor/owlcli/write/RdfWriterTest.java +++ b/ret-write/src/test/java/de/atextor/ret/write/RdfWriterTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.write; +package de.atextor.ret.write; import de.atextor.turtle.formatter.TurtleFormatter; import io.vavr.control.Try; diff --git a/write/build.gradle b/write/build.gradle deleted file mode 100644 index bfd95d12..00000000 --- a/write/build.gradle +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation(deps.jena) - implementation(deps.jena_core) - implementation(deps.jena_arq) - implementation(deps.slf4j_api) - implementation(deps.turtle_formatter) - implementation(deps.vavr) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.assertj) - testImplementation(deps.jqwik) - testRuntimeOnly(deps.junit_jupiter_engine) -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } -} - From fef7e528de433b9f3d24cbe13aca06438cb27d25 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 8 Nov 2023 05:30:38 +0100 Subject: [PATCH 145/280] Turn infer module into Maven module --- infer/build.gradle | 64 --------------- ret-infer/pom.xml | 77 +++++++++++++++++++ .../de/atextor/ret}/infer/Configuration.java | 4 +- .../java/de/atextor/ret}/infer/Inferrer.java | 4 +- .../de/atextor/ret}/infer/InferrerTest.java | 4 +- 5 files changed, 84 insertions(+), 69 deletions(-) delete mode 100644 infer/build.gradle create mode 100644 ret-infer/pom.xml rename {infer/src/main/java/de/atextor/owlcli => ret-infer/src/main/java/de/atextor/ret}/infer/Configuration.java (92%) rename {infer/src/main/java/de/atextor/owlcli => ret-infer/src/main/java/de/atextor/ret}/infer/Inferrer.java (96%) rename {infer/src/test/java/de/atextor/owlcli => ret-infer/src/test/java/de/atextor/ret}/infer/InferrerTest.java (94%) diff --git a/infer/build.gradle b/infer/build.gradle deleted file mode 100644 index ab4a5579..00000000 --- a/infer/build.gradle +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation(deps.jena) - implementation(deps.jena_core) - implementation(deps.slf4j_api) - implementation(deps.turtle_formatter) - implementation(deps.vavr) - implementation(deps.openllet) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.assertj) - testImplementation(deps.jqwik) - testRuntimeOnly(deps.junit_jupiter_engine) -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } -} - diff --git a/ret-infer/pom.xml b/ret-infer/pom.xml new file mode 100644 index 00000000..b150c1de --- /dev/null +++ b/ret-infer/pom.xml @@ -0,0 +1,77 @@ + + + + ret + de.atextor.ret + 1.0-SNAPSHOT + + 4.0.0 + + ret-infer + + + 17 + 17 + UTF-8 + + + + + + org.apache.jena + jena + pom + + + org.apache.jena + jena-core + + + org.slf4j + slf4j-api + + + de.atextor + turtle-formatter + + + io.vavr + vavr + + + com.github.galigator.openllet + openllet-jena + + + + + org.projectlombok + lombok + compile + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + net.jqwik + jqwik + test + + + \ No newline at end of file diff --git a/infer/src/main/java/de/atextor/owlcli/infer/Configuration.java b/ret-infer/src/main/java/de/atextor/ret/infer/Configuration.java similarity index 92% rename from infer/src/main/java/de/atextor/owlcli/infer/Configuration.java rename to ret-infer/src/main/java/de/atextor/ret/infer/Configuration.java index 902ca84c..6d7dab18 100644 --- a/infer/src/main/java/de/atextor/owlcli/infer/Configuration.java +++ b/ret-infer/src/main/java/de/atextor/ret/infer/Configuration.java @@ -14,16 +14,18 @@ * limitations under the License. */ -package de.atextor.owlcli.infer; +package de.atextor.ret.infer; import de.atextor.turtle.formatter.TurtleFormatter; import lombok.Builder; @Builder public class Configuration { + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public Format inputFormat = Format.TURTLE; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String base = TurtleFormatter.DEFAULT_EMPTY_BASE; diff --git a/infer/src/main/java/de/atextor/owlcli/infer/Inferrer.java b/ret-infer/src/main/java/de/atextor/ret/infer/Inferrer.java similarity index 96% rename from infer/src/main/java/de/atextor/owlcli/infer/Inferrer.java rename to ret-infer/src/main/java/de/atextor/ret/infer/Inferrer.java index f2bbb819..48fc2de6 100644 --- a/infer/src/main/java/de/atextor/owlcli/infer/Inferrer.java +++ b/ret-infer/src/main/java/de/atextor/ret/infer/Inferrer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.infer; +package de.atextor.ret.infer; import de.atextor.turtle.formatter.FormattingStyle; import de.atextor.turtle.formatter.TurtleFormatter; @@ -78,7 +78,7 @@ public Try writeTurtle( final Model model, final OutputStream output ) { } /** - * Builds a RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} + * Builds an RDF format string as expected by the lang parameter of {@link Model#read(InputStream, String, String)} * * @param format the format * @return the format identifier for the Jena parser diff --git a/infer/src/test/java/de/atextor/owlcli/infer/InferrerTest.java b/ret-infer/src/test/java/de/atextor/ret/infer/InferrerTest.java similarity index 94% rename from infer/src/test/java/de/atextor/owlcli/infer/InferrerTest.java rename to ret-infer/src/test/java/de/atextor/ret/infer/InferrerTest.java index 376a2d66..92839f5b 100644 --- a/infer/src/test/java/de/atextor/owlcli/infer/InferrerTest.java +++ b/ret-infer/src/test/java/de/atextor/ret/infer/InferrerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.infer; +package de.atextor.ret.infer; import org.junit.jupiter.api.Test; @@ -23,6 +23,6 @@ public class InferrerTest { @Test public void testFoo() { - + // TODO } } From db89ddb85173cae94a8521ca951f6a2733f82773 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 8 Nov 2023 05:31:49 +0100 Subject: [PATCH 146/280] Turn diagram module into Maven module --- diagram/build.gradle | 73 --------------- ret-diagram-owl/pom.xml | 82 +++++++++++++++++ .../ret/diagram/owl}/Configuration.java | 10 ++- .../ret/diagram/owl}/DiagramGenerator.java | 16 ++-- .../ret/diagram/owl}/FontEmbedder.java | 2 +- .../ret/diagram/owl}/GraphvizDocument.java | 2 +- .../ret/diagram/owl}/GraphvizGenerator.java | 90 +++++++++---------- .../de/atextor/ret/diagram/owl}/Template.java | 2 +- .../ret/diagram/owl}/ThrowingConsumer.java | 2 +- .../atextor/ret/diagram/owl}/graph/Edge.java | 11 ++- .../atextor/ret/diagram/owl}/graph/Graph.java | 6 +- .../ret/diagram/owl}/graph/GraphElement.java | 2 +- .../ret/diagram/owl}/graph/GraphVisitor.java | 4 +- .../atextor/ret/diagram/owl}/graph/Node.java | 86 +++++++++--------- .../owl}/graph/node/AnnotationProperty.java | 4 +- .../ret/diagram/owl}/graph/node/Class.java | 4 +- .../diagram/owl}/graph/node/ClosedClass.java | 4 +- .../diagram/owl}/graph/node/Complement.java | 4 +- .../owl}/graph/node/DataExactCardinality.java | 4 +- .../graph/node/DataMaximalCardinality.java | 4 +- .../graph/node/DataMinimalCardinality.java | 4 +- .../diagram/owl}/graph/node/DataProperty.java | 4 +- .../ret/diagram/owl}/graph/node/Datatype.java | 4 +- .../owl}/graph/node/DisjointUnion.java | 4 +- .../diagram/owl}/graph/node/Disjointness.java | 4 +- .../ret/diagram/owl}/graph/node/Equality.java | 4 +- .../graph/node/ExistentialRestriction.java | 4 +- .../diagram/owl}/graph/node/IRIReference.java | 7 +- .../diagram/owl}/graph/node/Individual.java | 4 +- .../diagram/owl}/graph/node/Inequality.java | 4 +- .../diagram/owl}/graph/node/Intersection.java | 4 +- .../ret/diagram/owl}/graph/node/Inverse.java | 4 +- .../diagram/owl}/graph/node/Invisible.java | 4 +- .../ret/diagram/owl}/graph/node/Key.java | 4 +- .../ret/diagram/owl}/graph/node/Literal.java | 4 +- .../graph/node/ObjectExactCardinality.java | 4 +- .../graph/node/ObjectMaximalCardinality.java | 4 +- .../graph/node/ObjectMinimalCardinality.java | 4 +- .../owl}/graph/node/ObjectProperty.java | 4 +- .../node/ObjectQualifiedExactCardinality.java | 4 +- .../ObjectQualifiedMaximalCardinality.java | 4 +- .../ObjectQualifiedMinimalCardinality.java | 4 +- .../owl}/graph/node/PropertyChain.java | 4 +- .../owl}/graph/node/PropertyMarker.java | 4 +- .../ret/diagram/owl}/graph/node/Rule.java | 4 +- .../ret/diagram/owl}/graph/node/Self.java | 6 +- .../ret/diagram/owl}/graph/node/Union.java | 4 +- .../owl}/graph/node/UniversalRestriction.java | 4 +- .../owl}/graph/node/ValueRestriction.java | 4 +- .../owl}/graph/transformer/ChangeSet.java | 4 +- .../graph/transformer/GraphTransformer.java | 8 +- .../transformer/IriReferenceResolver.java | 14 +-- .../transformer/PropertyMarkerMerger.java | 12 +-- .../graph/transformer/PunningRemover.java | 10 +-- .../owl}/mappers/DefaultIdentifierMapper.java | 4 +- .../mappers/DefaultMappingConfiguration.java | 12 +-- .../owl}/mappers/DefaultNameMapper.java | 2 +- .../owl}/mappers/IdentifierMapper.java | 4 +- .../owl}/mappers/MappingConfiguration.java | 4 +- .../ret/diagram/owl}/mappers/NameMapper.java | 2 +- .../mappers/OWLAnnotationObjectMapper.java | 8 +- .../diagram/owl}/mappers/OWLAxiomMapper.java | 45 +++++----- .../mappers/OWLClassExpressionMapper.java | 46 +++++----- .../diagram/owl}/mappers/OWLDataMapper.java | 22 ++--- .../diagram/owl}/mappers/OWLEntityMapper.java | 16 ++-- .../owl}/mappers/OWLIndividualMapper.java | 8 +- .../diagram/owl}/mappers/OWLObjectMapper.java | 4 +- .../owl}/mappers/OWLOntologyMapper.java | 16 ++-- .../mappers/OWLPropertyExpressionMapper.java | 16 ++-- .../owl}/mappers/SWRLObjectMapper.java | 14 +-- .../printers/OWLClassExpressionPrinter.java | 4 +- .../diagram/owl}/printers/OWLDataPrinter.java | 4 +- .../owl}/printers/OWLIndividualPrinter.java | 6 +- .../OWLPropertyExpressionPrinter.java | 4 +- .../diagram/owl}/DiagramGeneratorTest.java | 84 ++++++++--------- .../diagram/owl}/GraphvizGeneratorTest.java | 68 +++++++------- .../ret/diagram/owl}/MapperTestBase.java | 29 +++--- .../owl}/OWLAnnotationObjectMapperTest.java | 12 +-- .../ret/diagram/owl}/OWLAxiomMapperTest.java | 33 +++---- .../owl}/OWLClassExpressionMapperTest.java | 46 +++++----- .../ret/diagram/owl}/OWLDataMapperTest.java | 26 +++--- .../ret/diagram/owl}/OWLEntityMapperTest.java | 10 ++- .../diagram/owl}/OWLIndividualMapperTest.java | 10 +-- .../diagram/owl}/OWLOntologyMapperTest.java | 22 ++--- .../owl}/OWLPropertyExpressionMapperTest.java | 16 ++-- .../diagram/owl}/SWRLObjectMapperTest.java | 18 ++-- .../diagram/owl}/TestIdentifierMapper.java | 6 +- .../ret/diagram/owl}/TestNameMapper.java | 4 +- 88 files changed, 622 insertions(+), 584 deletions(-) delete mode 100644 diagram/build.gradle create mode 100644 ret-diagram-owl/pom.xml rename {diagram/src/main/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/Configuration.java (86%) rename {diagram/src/main/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/DiagramGenerator.java (93%) rename {diagram/src/main/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/FontEmbedder.java (99%) rename {diagram/src/main/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/GraphvizDocument.java (99%) rename {diagram/src/main/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/GraphvizGenerator.java (87%) rename {diagram/src/main/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/Template.java (97%) rename {diagram/src/main/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/ThrowingConsumer.java (95%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/Edge.java (96%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/Graph.java (94%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/GraphElement.java (97%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/GraphVisitor.java (94%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/Node.java (64%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/AnnotationProperty.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Class.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ClosedClass.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Complement.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/DataExactCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/DataMaximalCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/DataMinimalCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/DataProperty.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Datatype.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/DisjointUnion.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Disjointness.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Equality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ExistentialRestriction.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/IRIReference.java (84%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Individual.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Inequality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Intersection.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Inverse.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Invisible.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Key.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Literal.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ObjectExactCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ObjectMaximalCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ObjectMinimalCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ObjectProperty.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ObjectQualifiedExactCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ObjectQualifiedMaximalCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ObjectQualifiedMinimalCardinality.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/PropertyChain.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/PropertyMarker.java (93%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Rule.java (92%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Self.java (83%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/Union.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/UniversalRestriction.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/node/ValueRestriction.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/transformer/ChangeSet.java (93%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/transformer/GraphTransformer.java (92%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/transformer/IriReferenceResolver.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/transformer/PropertyMarkerMerger.java (92%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/graph/transformer/PunningRemover.java (93%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/DefaultIdentifierMapper.java (93%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/DefaultMappingConfiguration.java (97%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/DefaultNameMapper.java (96%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/IdentifierMapper.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/MappingConfiguration.java (96%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/NameMapper.java (95%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLAnnotationObjectMapper.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLAxiomMapper.java (95%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLClassExpressionMapper.java (91%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLDataMapper.java (88%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLEntityMapper.java (87%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLIndividualMapper.java (90%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLObjectMapper.java (98%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLOntologyMapper.java (77%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/OWLPropertyExpressionMapper.java (87%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/mappers/SWRLObjectMapper.java (96%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/printers/OWLClassExpressionPrinter.java (98%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/printers/OWLDataPrinter.java (96%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/printers/OWLIndividualPrinter.java (89%) rename {diagram/src/main/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl}/printers/OWLPropertyExpressionPrinter.java (94%) rename {diagram/src/test/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/DiagramGeneratorTest.java (74%) rename {diagram/src/test/java/de/atextor/owlcli/diagram/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/GraphvizGeneratorTest.java (80%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/MapperTestBase.java (92%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLAnnotationObjectMapperTest.java (89%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLAxiomMapperTest.java (98%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLClassExpressionMapperTest.java (96%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLDataMapperTest.java (94%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLEntityMapperTest.java (85%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLIndividualMapperTest.java (90%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLOntologyMapperTest.java (93%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/OWLPropertyExpressionMapperTest.java (90%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/SWRLObjectMapperTest.java (96%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/TestIdentifierMapper.java (91%) rename {diagram/src/test/java/de/atextor/owlcli/diagram => ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl}/TestNameMapper.java (91%) diff --git a/diagram/build.gradle b/diagram/build.gradle deleted file mode 100644 index 8363ef48..00000000 --- a/diagram/build.gradle +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation(deps.guava) - implementation(deps.owlapi) { - exclude group: 'org.slf4j', module: 'slf4j-simple' - } - implementation(deps.slf4j_api) - implementation(deps.vavr) - implementation(deps.commons_text) - - // Override transitive dependency versions due to features - implementation(deps.caffeine) - - // Override transitive dependency versions due to vulns - implementation(deps.jackson_databind) - implementation(deps.httpclient) - implementation(deps.commons_codec) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.assertj) - testImplementation(deps.jqwik) - testRuntimeOnly(deps.junit_jupiter_engine) -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } -} - diff --git a/ret-diagram-owl/pom.xml b/ret-diagram-owl/pom.xml new file mode 100644 index 00000000..aa68ea12 --- /dev/null +++ b/ret-diagram-owl/pom.xml @@ -0,0 +1,82 @@ + + + + ret + de.atextor.ret + 1.0-SNAPSHOT + + 4.0.0 + + ret-diagram-owl + + + 17 + 17 + UTF-8 + + + + + + com.github.ben-manes.caffeine + caffeine + + + org.apache.commons + commons-text + + + com.google.guava + guava + + + net.sourceforge.owlapi + owlapi-distribution + + + org.slf4j + slf4j-simple + + + + + org.slf4j + slf4j-api + + + io.vavr + vavr + + + + + org.projectlombok + lombok + compile + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.assertj + assertj-core + test + + + net.jqwik + jqwik + test + + + \ No newline at end of file diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Configuration.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Configuration.java similarity index 86% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Configuration.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Configuration.java index 55b5cb5f..3f7ee4fe 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Configuration.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Configuration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package de.atextor.ret.diagram.owl; import lombok.Builder; @@ -23,39 +23,47 @@ */ @Builder public class Configuration { + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String dotBinary = "dot"; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String fontname = "Verdana"; @Builder.Default public int fontsize = 12; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String nodeFontname = "Verdana"; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public int nodeFontsize = 12; @Builder.Default public String nodeShape = "box"; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String nodeMargin = "0.05,0.0"; @Builder.Default public String nodeStyle = "rounded"; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String bgColor = "white"; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public String fgColor = "black"; @Builder.Default public Format format = Format.SVG; + @SuppressWarnings( "CanBeFinal" ) @Builder.Default public LayoutDirection layoutDirection = LayoutDirection.LEFT_TO_RIGHT; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/DiagramGenerator.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java similarity index 93% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/DiagramGenerator.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java index 78899729..9319e51f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/DiagramGenerator.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package de.atextor.ret.diagram.owl; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLOntologyMapper; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.OWLOntologyMapper; import io.vavr.control.Try; import org.apache.commons.io.IOUtils; import org.semanticweb.owlapi.model.OWLOntology; @@ -51,7 +51,7 @@ public class DiagramGenerator { /** * Constructor. Initializes the Diagram generator with the necessary configuration. * - * @param configuration the configuration to provide to the Graphviz Genenerator + * @param configuration the configuration to provide to the Graphviz Generator * @param mappingConfig the mapping configuration to fine-tune the ontology mapping operation */ public DiagramGenerator( final Configuration configuration, final MappingConfiguration mappingConfig ) { @@ -90,7 +90,7 @@ Try executeDot( final ThrowingConsumer contentP !graphvizStderr.startsWith( "Warning:" ) && !graphvizStderr.contains( "Pango-WARNING" ) ) { LOG.debug( "Dot returned an error: {}", graphvizStderr ); - return Try.failure( new RuntimeException( "An error occured while running dot. This is most likely " + return Try.failure( new RuntimeException( "An error occurred while running dot. This is most likely " + "due to a bug in owl-cli. Captured message was: " + graphvizStderr ) ); } @@ -104,7 +104,7 @@ Try executeDot( final ThrowingConsumer contentP } final String svgOutput = new String( graphvizStdout, StandardCharsets.UTF_8 ); - return postprocess( svgOutput ).flatMap( processedOutput -> + return postProcess( svgOutput ).flatMap( processedOutput -> writeStreamToOutput( processedOutput, output ).flatMap( writingResult -> { LOG.debug( "Writing to output {}", output ); try { @@ -119,7 +119,7 @@ Try executeDot( final ThrowingConsumer contentP } } - private Try postprocess( final String dotOutput ) { + private Try postProcess( final String dotOutput ) { return svgPostProcessors.stream().sequential().reduce( Function.identity(), Function::andThen ) .apply( Try.success( dotOutput ) ) .map( string -> IOUtils.toInputStream( string, StandardCharsets.UTF_8 ) ); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/FontEmbedder.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java similarity index 99% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/FontEmbedder.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java index 00c4eeb4..fcf68e3d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/FontEmbedder.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package de.atextor.ret.diagram.owl; import io.vavr.control.Try; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizDocument.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java similarity index 99% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizDocument.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java index 8e6ace27..0ece62de 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizDocument.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package de.atextor.ret.diagram.owl; import com.google.common.collect.ImmutableMap; import lombok.AccessLevel; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizGenerator.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java similarity index 87% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizGenerator.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java index e81379c8..a71bdc22 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/GraphvizGenerator.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java @@ -14,48 +14,48 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package de.atextor.ret.diagram.owl; +import de.atextor.ret.diagram.owl.graph.node.Class; import com.google.common.collect.Ordering; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.GraphVisitor; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Rule; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.GraphVisitor; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.DataExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataProperty; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.DisjointUnion; +import de.atextor.ret.diagram.owl.graph.node.Disjointness; +import de.atextor.ret.diagram.owl.graph.node.Equality; +import de.atextor.ret.diagram.owl.graph.node.ExistentialRestriction; +import de.atextor.ret.diagram.owl.graph.node.IRIReference; +import de.atextor.ret.diagram.owl.graph.node.Individual; +import de.atextor.ret.diagram.owl.graph.node.Inequality; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.Inverse; +import de.atextor.ret.diagram.owl.graph.node.Invisible; +import de.atextor.ret.diagram.owl.graph.node.Key; +import de.atextor.ret.diagram.owl.graph.node.Literal; +import de.atextor.ret.diagram.owl.graph.node.ObjectExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectProperty; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.PropertyChain; +import de.atextor.ret.diagram.owl.graph.node.PropertyMarker; +import de.atextor.ret.diagram.owl.graph.node.Rule; +import de.atextor.ret.diagram.owl.graph.node.Self; +import de.atextor.ret.diagram.owl.graph.node.Union; +import de.atextor.ret.diagram.owl.graph.node.UniversalRestriction; +import de.atextor.ret.diagram.owl.graph.node.ValueRestriction; import org.apache.commons.text.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -170,11 +170,11 @@ private enum Symbol { INDIVIDUAL( "#874B82", "◆", 14 ), DATA_TYPE( "#AD3B45", "⬤", 12 ); - String color; + final String color; - String symbol; + final String symbol; - int symbolSize; + final int symbolSize; Symbol( final String color, final String symbol, final int symbolSize ) { this.color = color; @@ -183,7 +183,7 @@ private enum Symbol { } /** - * Returns a DOT fragement for an element with this symbol. Note that the referenced font 'owlcli' + * Returns a DOT fragment for an element with this symbol. Note that the referenced font 'owlcli' * is injected during rendering using the {@link FontEmbedder}. * * @param elementName the name of the element @@ -207,7 +207,7 @@ String getNodeValue( final String elementName, final Configuration configuration final Template invisibleNodeTemplate = new Template( """ ${nodeId} [label="", width="0", style="invis"] """ ); - Configuration configuration; + final Configuration configuration; GraphvizNodeVisitor( final Configuration configuration ) { this.configuration = configuration; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Template.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java similarity index 97% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Template.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java index 0351d43f..355a1eed 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/Template.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package de.atextor.ret.diagram.owl; import java.util.Map; import java.util.function.Function; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/ThrowingConsumer.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/ThrowingConsumer.java similarity index 95% rename from diagram/src/main/java/de/atextor/owlcli/diagram/diagram/ThrowingConsumer.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/ThrowingConsumer.java index 82b3318f..3bf43dc9 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/diagram/ThrowingConsumer.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/ThrowingConsumer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; +package de.atextor.ret.diagram.owl; /** * See {@link java.util.function.Consumer} diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Edge.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Edge.java similarity index 96% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/Edge.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Edge.java index 5534b04b..c6d6a497 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Edge.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Edge.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; +package de.atextor.ret.diagram.owl.graph; import lombok.EqualsAndHashCode; import lombok.Value; @@ -38,7 +38,7 @@ private Edge() { public abstract Node getTo(); - public abstract Edge.Type getType(); + public abstract Type getType(); public abstract Edge setFrom( Node newFromId ); @@ -58,7 +58,9 @@ public Edge asEdge() { @EqualsAndHashCode( callSuper = true ) public static class Plain extends Edge { Type type; + Node from; + Node to; @Override @@ -90,7 +92,7 @@ public enum Label { RANGE( "range" ), DOMAIN( "domain" ); - String label; + final String label; Label( final String label ) { this.label = label; @@ -102,8 +104,11 @@ public String getLabel() { } Type type; + Node from; + Node to; + Label label; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Graph.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Graph.java similarity index 94% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/Graph.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Graph.java index 9788a419..3271bb7d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Graph.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Graph.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; +package de.atextor.ret.diagram.owl.graph; import lombok.Getter; @@ -27,8 +27,8 @@ */ @Getter public class Graph { - Node node; - Stream otherElements; + final Node node; + final Stream otherElements; protected Graph( final Node node, final Stream otherElements ) { this.node = node; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphElement.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphElement.java similarity index 97% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphElement.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphElement.java index 3157b917..62557ca1 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphElement.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphElement.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; +package de.atextor.ret.diagram.owl.graph; import java.util.stream.Stream; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphVisitor.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphVisitor.java similarity index 94% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphVisitor.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphVisitor.java index d1bd2120..ecf94cf6 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/GraphVisitor.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphVisitor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; +package de.atextor.ret.diagram.owl.graph; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -23,7 +23,7 @@ import java.util.function.Function; /** - * Visitor for a elements of a graph + * Visitor for elements of a graph * * @param the result type of the visit operation */ diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Node.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Node.java similarity index 64% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/Node.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Node.java index 5c5db841..105dd14f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/Node.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Node.java @@ -14,43 +14,43 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph; - -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Rule; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; +package de.atextor.ret.diagram.owl.graph; + +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.graph.node.Class; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.DataExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataProperty; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.DisjointUnion; +import de.atextor.ret.diagram.owl.graph.node.Disjointness; +import de.atextor.ret.diagram.owl.graph.node.Equality; +import de.atextor.ret.diagram.owl.graph.node.ExistentialRestriction; +import de.atextor.ret.diagram.owl.graph.node.IRIReference; +import de.atextor.ret.diagram.owl.graph.node.Individual; +import de.atextor.ret.diagram.owl.graph.node.Inequality; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.Inverse; +import de.atextor.ret.diagram.owl.graph.node.Invisible; +import de.atextor.ret.diagram.owl.graph.node.Key; +import de.atextor.ret.diagram.owl.graph.node.Literal; +import de.atextor.ret.diagram.owl.graph.node.ObjectExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectProperty; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.PropertyChain; +import de.atextor.ret.diagram.owl.graph.node.PropertyMarker; +import de.atextor.ret.diagram.owl.graph.node.Rule; +import de.atextor.ret.diagram.owl.graph.node.Self; +import de.atextor.ret.diagram.owl.graph.node.Union; +import de.atextor.ret.diagram.owl.graph.node.UniversalRestriction; +import de.atextor.ret.diagram.owl.graph.node.ValueRestriction; import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -146,14 +146,14 @@ public interface Visitor { } /** - * Id of a node that has the (unique) internal identifier string, and if present, the {@link IRI} of the - * ontology element that is represented by the node having this Id. + * ID of a node that has the (unique) internal identifier string, and if present, the {@link IRI} of the + * ontology element that is represented by the node having this ID. */ @Getter @EqualsAndHashCode public static class Id { - String id; - Optional iri; + final String id; + final Optional iri; public Id( final String id, final IRI iri ) { this.id = id; @@ -187,11 +187,11 @@ public T accept( final GraphElement.Visitor visitor ) { return visitor.visit( this ); } - public abstract Node.Id getId(); + public abstract Id getId(); public abstract T accept( final Visitor visitor ); - public abstract Node withId( Node.Id newId ); + public abstract Node withId( Id newId ); @Override public boolean isNode() { diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/AnnotationProperty.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/AnnotationProperty.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/AnnotationProperty.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/AnnotationProperty.java index d4273cfd..f7bbafce 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/AnnotationProperty.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/AnnotationProperty.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Class.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Class.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Class.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Class.java index e52fe4d0..53ec6c81 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Class.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Class.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ClosedClass.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ClosedClass.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ClosedClass.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ClosedClass.java index 1a7bce6c..719b61de 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ClosedClass.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ClosedClass.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Complement.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Complement.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Complement.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Complement.java index 68f148e6..0b2f841d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Complement.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Complement.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataExactCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataExactCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataExactCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataExactCardinality.java index 7b9afd58..8759f5d4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataExactCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataExactCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMaximalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMaximalCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMaximalCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMaximalCardinality.java index 0d228dd2..900ba036 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMaximalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMaximalCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMinimalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMinimalCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMinimalCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMinimalCardinality.java index 12e6a559..72eafc91 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataMinimalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMinimalCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataProperty.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataProperty.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataProperty.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataProperty.java index 5f98ff7a..3c9579bf 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DataProperty.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataProperty.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Datatype.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Datatype.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Datatype.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Datatype.java index 6ed541ff..681f1f5f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Datatype.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Datatype.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DisjointUnion.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DisjointUnion.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DisjointUnion.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DisjointUnion.java index 137e20cb..f68ac8ed 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/DisjointUnion.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DisjointUnion.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Disjointness.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Disjointness.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Disjointness.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Disjointness.java index 109cf3b2..c62c1855 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Disjointness.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Disjointness.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Equality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Equality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Equality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Equality.java index d51b2d54..552da5f1 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Equality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Equality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ExistentialRestriction.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ExistentialRestriction.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ExistentialRestriction.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ExistentialRestriction.java index 76aa457f..dc4dc805 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ExistentialRestriction.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ExistentialRestriction.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/IRIReference.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/IRIReference.java similarity index 84% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/IRIReference.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/IRIReference.java index ef043e65..bac3e6bf 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/IRIReference.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/IRIReference.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; @@ -25,7 +25,7 @@ /** * Represents a reference to some yet unknown other graph that has a {@link Node.Id} with a given {@link IRI}. * This type of node should never end up in the final graph, as it is resolved by the - * {@link de.atextor.owlcli.diagram.graph.transformer.IriReferenceResolver} after the Axiom -> Graph Elements mapping + * {@link de.atextor.ret.diagram.owl.graph.transformer.IriReferenceResolver} after the Axiom -> Graph Elements mapping * is done. */ @Value @@ -33,6 +33,7 @@ @With public class IRIReference extends Node.InvisibleNode { Id id; + IRI iri; @Override diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Individual.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Individual.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Individual.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Individual.java index db456bdd..36aaef7d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Individual.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Individual.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inequality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inequality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inequality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inequality.java index f686c266..b6e3249e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inequality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inequality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Intersection.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Intersection.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Intersection.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Intersection.java index 16da01fc..a2501c61 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Intersection.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Intersection.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inverse.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inverse.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inverse.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inverse.java index a4f03027..a0f87c72 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Inverse.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inverse.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Invisible.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Invisible.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Invisible.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Invisible.java index 1d29029b..1576fbe3 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Invisible.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Invisible.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Key.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Key.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Key.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Key.java index 188286f1..1f6f6d81 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Key.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Key.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Literal.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Literal.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Literal.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Literal.java index 3e10e0b5..cd4786b2 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Literal.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Literal.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectExactCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectExactCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectExactCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectExactCardinality.java index 313d7a92..b50ae94d 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectExactCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectExactCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMaximalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMaximalCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMaximalCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMaximalCardinality.java index d94ba38d..4dcc582e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMaximalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMaximalCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMinimalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMinimalCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMinimalCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMinimalCardinality.java index b6f85c29..ba536512 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectMinimalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMinimalCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectProperty.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectProperty.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectProperty.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectProperty.java index 9fe21265..c7e147f4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectProperty.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectProperty.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedExactCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedExactCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java index 0eb160c7..f8242a55 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedExactCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMaximalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMaximalCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java index 68f559c2..3d89da13 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMaximalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMinimalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMinimalCardinality.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java index 263a569c..b76e8621 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ObjectQualifiedMinimalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyChain.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyChain.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyChain.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyChain.java index edbcda2e..554f69c4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyChain.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyChain.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyMarker.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyMarker.java similarity index 93% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyMarker.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyMarker.java index 65ab285d..9f77569c 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/PropertyMarker.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyMarker.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Rule.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Rule.java similarity index 92% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Rule.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Rule.java index 9b2a56cc..bc0048f8 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Rule.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Rule.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Self.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Self.java similarity index 83% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Self.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Self.java index 2e72846e..6a458397 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Self.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Self.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; /** - * Represents a OWL Object Property self restriction symbol ("self") node in the graph. + * Represents an OWL Object Property self restriction symbol ("self") node in the graph. */ @Value @EqualsAndHashCode( callSuper = true ) diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Union.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Union.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Union.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Union.java index 472b33b8..9ba2b475 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/Union.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Union.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/UniversalRestriction.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/UniversalRestriction.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/UniversalRestriction.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/UniversalRestriction.java index 60e4e6ab..5daa18fb 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/UniversalRestriction.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/UniversalRestriction.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ValueRestriction.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ValueRestriction.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ValueRestriction.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ValueRestriction.java index 7805d6f4..04b606cd 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/node/ValueRestriction.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ValueRestriction.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.node; +package de.atextor.ret.diagram.owl.graph.node; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import lombok.EqualsAndHashCode; import lombok.Value; import lombok.With; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/ChangeSet.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/ChangeSet.java similarity index 93% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/ChangeSet.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/ChangeSet.java index 6de85a9d..98b04aae 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/ChangeSet.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/ChangeSet.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package de.atextor.ret.diagram.owl.graph.transformer; import com.google.common.collect.Sets; -import de.atextor.owlcli.diagram.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.GraphElement; import lombok.Value; import java.util.Set; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/GraphTransformer.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/GraphTransformer.java similarity index 92% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/GraphTransformer.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/GraphTransformer.java index ced12b8a..cd43ce06 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/GraphTransformer.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/GraphTransformer.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package de.atextor.ret.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; import org.semanticweb.owlapi.model.IRI; import java.util.Set; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/IriReferenceResolver.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/IriReferenceResolver.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/IriReferenceResolver.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/IriReferenceResolver.java index 7a06e818..39415da7 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/IriReferenceResolver.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/IriReferenceResolver.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package de.atextor.ret.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.IRIReference; +import de.atextor.ret.diagram.owl.graph.node.Literal; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,7 +51,7 @@ public IriReferenceResolver( final MappingConfiguration mappingConfiguration ) { * Apply this transformer to the given input graph * * @param graph the input graph - * @return the resulting graph that contains no {@link IRIReference}s any more + * @return the resulting graph that contains no {@link IRIReference}s anymore */ @Override public Set apply( final Set graph ) { diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PropertyMarkerMerger.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PropertyMarkerMerger.java similarity index 92% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PropertyMarkerMerger.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PropertyMarkerMerger.java index 792e3ecb..02bfc318 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PropertyMarkerMerger.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PropertyMarkerMerger.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package de.atextor.ret.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.PropertyMarker; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import io.vavr.Tuple2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PunningRemover.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PunningRemover.java similarity index 93% rename from diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PunningRemover.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PunningRemover.java index 7f6bea47..4c9464ad 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/graph/transformer/PunningRemover.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PunningRemover.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.graph.transformer; +package de.atextor.ret.diagram.owl.graph.transformer; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,7 +31,7 @@ * Implements a graph transformer that resolves * Punning in a graph: An input ontology that * uses punning for e.g. an individual and a class results in a graph that contains both the individual and the class - * as nodes, but both share the same {@link Node.Id}, as it is derived from the the element's + * as nodes, but both share the same {@link Node.Id}, as it is derived from the element's * {@link org.semanticweb.owlapi.model.IRI}. This transformer replaces the nodes with new, uniquely identified nodes * (that keep the original IRI in their IDs) and updates all edges in the graph accordingly. */ diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultIdentifierMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultIdentifierMapper.java similarity index 93% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultIdentifierMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultIdentifierMapper.java index ef644754..e273668f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultIdentifierMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultIdentifierMapper.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import org.semanticweb.owlapi.model.IRI; import java.util.UUID; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultMappingConfiguration.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultMappingConfiguration.java similarity index 97% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultMappingConfiguration.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultMappingConfiguration.java index 42c101c1..37dbcfde 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultMappingConfiguration.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultMappingConfiguration.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.printers.OWLClassExpressionPrinter; -import de.atextor.owlcli.diagram.printers.OWLDataPrinter; -import de.atextor.owlcli.diagram.printers.OWLIndividualPrinter; -import de.atextor.owlcli.diagram.printers.OWLPropertyExpressionPrinter; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.printers.OWLClassExpressionPrinter; +import de.atextor.ret.diagram.owl.printers.OWLDataPrinter; +import de.atextor.ret.diagram.owl.printers.OWLIndividualPrinter; +import de.atextor.ret.diagram.owl.printers.OWLPropertyExpressionPrinter; import org.semanticweb.owlapi.model.OWLAnnotationObjectVisitorEx; import org.semanticweb.owlapi.model.OWLAnnotationSubjectVisitorEx; import org.semanticweb.owlapi.model.OWLAxiomVisitorEx; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultNameMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultNameMapper.java similarity index 96% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultNameMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultNameMapper.java index 366ec0f9..12aaa896 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/DefaultNameMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultNameMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; import org.semanticweb.owlapi.model.HasIRI; import org.semanticweb.owlapi.model.IRI; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/IdentifierMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/IdentifierMapper.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/IdentifierMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/IdentifierMapper.java index a2e9eecb..874db5f4 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/IdentifierMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/IdentifierMapper.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Node; +import de.atextor.ret.diagram.owl.graph.Node; import org.semanticweb.owlapi.model.IRI; /** diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/MappingConfiguration.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/MappingConfiguration.java similarity index 96% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/MappingConfiguration.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/MappingConfiguration.java index 4d99f46d..92de491f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/MappingConfiguration.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/MappingConfiguration.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; +import de.atextor.ret.diagram.owl.graph.Graph; import org.semanticweb.owlapi.model.OWLAnnotationObjectVisitorEx; import org.semanticweb.owlapi.model.OWLAnnotationSubjectVisitorEx; import org.semanticweb.owlapi.model.OWLAxiomVisitorEx; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/NameMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/NameMapper.java similarity index 95% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/NameMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/NameMapper.java index 7554a357..95770ace 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/NameMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/NameMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; import org.semanticweb.owlapi.model.HasIRI; import org.semanticweb.owlapi.model.IRI; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAnnotationObjectMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAnnotationObjectMapper.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAnnotationObjectMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAnnotationObjectMapper.java index 636eb2e6..7fc52379 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAnnotationObjectMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAnnotationObjectMapper.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.IRIReference; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.IRIReference; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLAnnotation; import org.semanticweb.owlapi.model.OWLAnnotationObjectVisitorEx; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAxiomMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAxiomMapper.java similarity index 95% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAxiomMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAxiomMapper.java index c7de43a1..d72278fa 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLAxiomMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAxiomMapper.java @@ -14,26 +14,26 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; import com.google.common.collect.Sets; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Rule; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.DisjointUnion; +import de.atextor.ret.diagram.owl.graph.node.Disjointness; +import de.atextor.ret.diagram.owl.graph.node.Equality; +import de.atextor.ret.diagram.owl.graph.node.IRIReference; +import de.atextor.ret.diagram.owl.graph.node.Inequality; +import de.atextor.ret.diagram.owl.graph.node.Inverse; +import de.atextor.ret.diagram.owl.graph.node.Invisible; +import de.atextor.ret.diagram.owl.graph.node.Key; +import de.atextor.ret.diagram.owl.graph.node.Literal; +import de.atextor.ret.diagram.owl.graph.node.PropertyChain; +import de.atextor.ret.diagram.owl.graph.node.PropertyMarker; +import de.atextor.ret.diagram.owl.graph.node.Rule; import org.semanticweb.owlapi.model.HasOperands; import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; import org.semanticweb.owlapi.model.OWLAnnotationPropertyDomainAxiom; @@ -404,8 +404,7 @@ public Graph visit( final @Nonnull OWLSubPropertyChainOfAxiom axiom ) { final OWLPropertyExpressionVisitorEx mapper = mappingConfig.getOwlPropertyExpressionMapper(); final List chainLinks = axiom.getPropertyChain().stream() - .map( expression -> expression.accept( mapper ).getNode() ) - .collect( Collectors.toList() ); + .map( expression -> expression.accept( mapper ).getNode() ).toList(); final String value = chainLinks.stream() .flatMap( node -> node.getId().getIri().stream() ) .map( iri -> mappingConfig.getNameMapper().getName( iri ) ) @@ -503,7 +502,7 @@ public Graph visit( final @Nonnull OWLAnnotationPropertyRangeAxiom axiom ) { @Override public Graph visit( final @Nonnull SWRLRule rule ) { - final Function, String> reduceWithConjuction = stream -> + final Function, String> reduceWithConjunction = stream -> stream.map( element -> element.as( Literal.class ) ) .map( Literal::getValue ) .collect( Collectors.joining( " " + Rule.CONJUNCTION_SYMBOL + " " ) ); @@ -512,13 +511,13 @@ public Graph visit( final @Nonnull SWRLRule rule ) { rule.body().flatMap( atom -> atom.accept( mappingConfig.getSwrlObjectMapper() ).toStream() ) .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); - final String bodyExpression = reduceWithConjuction.apply( partitionedBodyElements.get( true ).stream() ); + final String bodyExpression = reduceWithConjunction.apply( partitionedBodyElements.get( true ).stream() ); final Map> partitionedHeadElements = rule.head().flatMap( atom -> atom.accept( mappingConfig.getSwrlObjectMapper() ).toStream() ) .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); - final String headExpression = reduceWithConjuction.apply( partitionedHeadElements.get( true ).stream() ); + final String headExpression = reduceWithConjunction.apply( partitionedHeadElements.get( true ).stream() ); final Node ruleNode = new Rule( mappingConfig.getIdentifierMapper().getSyntheticId(), String.format( "%s %s %s", bodyExpression, Rule.IMPLICATION_SYMBOL, headExpression ) ); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLClassExpressionMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLClassExpressionMapper.java similarity index 91% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLClassExpressionMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLClassExpressionMapper.java index bd9ebc0a..03d235d6 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLClassExpressionMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLClassExpressionMapper.java @@ -14,30 +14,30 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Class; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.DataExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ExistentialRestriction; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.ObjectExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.Self; +import de.atextor.ret.diagram.owl.graph.node.Union; +import de.atextor.ret.diagram.owl.graph.node.UniversalRestriction; +import de.atextor.ret.diagram.owl.graph.node.ValueRestriction; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLClassExpression; import org.semanticweb.owlapi.model.OWLClassExpressionVisitorEx; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLDataMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLDataMapper.java similarity index 88% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLDataMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLDataMapper.java index d4031631..98da3b41 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLDataMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLDataMapper.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.Union; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.Literal; +import de.atextor.ret.diagram.owl.graph.node.Union; import org.semanticweb.owlapi.model.OWLDataComplementOf; import org.semanticweb.owlapi.model.OWLDataIntersectionOf; import org.semanticweb.owlapi.model.OWLDataOneOf; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLEntityMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLEntityMapper.java similarity index 87% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLEntityMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLEntityMapper.java index bb8c29f2..27b29d72 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLEntityMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLEntityMapper.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.graph.node.Class; +import de.atextor.ret.diagram.owl.graph.node.DataProperty; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.ObjectProperty; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLDataProperty; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLIndividualMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLIndividualMapper.java similarity index 90% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLIndividualMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLIndividualMapper.java index 139f024b..d17fcf7e 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLIndividualMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLIndividualMapper.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Individual; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Individual; import org.semanticweb.owlapi.model.OWLAnonymousIndividual; import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; import org.semanticweb.owlapi.model.OWLNamedIndividual; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLObjectMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLObjectMapper.java similarity index 98% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLObjectMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLObjectMapper.java index 1de749f8..a3d08552 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLObjectMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLObjectMapper.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; +import de.atextor.ret.diagram.owl.graph.Graph; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLDataAllValuesFrom; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLOntologyMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLOntologyMapper.java similarity index 77% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLOntologyMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLOntologyMapper.java index 65bc85a8..71c1f8a3 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLOntologyMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLOntologyMapper.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.transformer.IriReferenceResolver; -import de.atextor.owlcli.diagram.graph.transformer.PropertyMarkerMerger; -import de.atextor.owlcli.diagram.graph.transformer.PunningRemover; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.transformer.IriReferenceResolver; +import de.atextor.ret.diagram.owl.graph.transformer.PropertyMarkerMerger; +import de.atextor.ret.diagram.owl.graph.transformer.PunningRemover; import org.semanticweb.owlapi.model.OWLOntology; import java.util.List; @@ -30,8 +30,8 @@ /** * Main class for mapping an {@link OWLOntology} to a {@link Graph}. The mapping is done in two steps: - * First, all axioms in the ontology are separatly mapped using the respective OWL*Mappers into nodes and edges. - * Secondly, the {@link de.atextor.owlcli.diagram.graph.transformer.GraphTransformer}s clean up the graph by + * First, all axioms in the ontology are separately mapped using the respective OWL*Mappers into nodes and edges. + * Secondly, the {@link de.atextor.ret.diagram.owl.graph.transformer.GraphTransformer}s clean up the graph by * performing changes that take the context of the whole graph into account. */ public class OWLOntologyMapper implements Function> { diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLPropertyExpressionMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLPropertyExpressionMapper.java similarity index 87% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLPropertyExpressionMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLPropertyExpressionMapper.java index bad74a47..79909f3f 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/OWLPropertyExpressionMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLPropertyExpressionMapper.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.graph.node.DataProperty; +import de.atextor.ret.diagram.owl.graph.node.Inverse; +import de.atextor.ret.diagram.owl.graph.node.ObjectProperty; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLDataProperty; import org.semanticweb.owlapi.model.OWLObjectInverseOf; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/SWRLObjectMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/SWRLObjectMapper.java similarity index 96% rename from diagram/src/main/java/de/atextor/owlcli/diagram/mappers/SWRLObjectMapper.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/SWRLObjectMapper.java index b9631717..319c5598 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/mappers/SWRLObjectMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/SWRLObjectMapper.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.mappers; +package de.atextor.ret.diagram.owl.mappers; -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Literal; +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Literal; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLPropertyExpression; import org.semanticweb.owlapi.model.SWRLArgument; @@ -54,7 +54,7 @@ public class SWRLObjectMapper implements SWRLObjectVisitorEx { * to render the final rule representation. In order to differentiate the to-be-concatenated * Literal nodes from "regular" Literal nodes that might occur, they are given an internal * identifier "marker" IRI. The concatenation is done in - * {@link de.atextor.owlcli.diagram.mappers.OWLAxiomMapper#visit(SWRLRule)}. + * {@link de.atextor.ret.diagram.owl.mappers.OWLAxiomMapper#visit(SWRLRule)}. */ private static final IRI LITERAL_ID = IRI.create( "urn:owl-cli:literal-id" ); diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLClassExpressionPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLClassExpressionPrinter.java similarity index 98% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLClassExpressionPrinter.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLClassExpressionPrinter.java index ee9a6cd7..351d2ae6 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLClassExpressionPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLClassExpressionPrinter.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package de.atextor.ret.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.HasCardinality; import org.semanticweb.owlapi.model.HasFiller; import org.semanticweb.owlapi.model.OWLClass; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLDataPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLDataPrinter.java similarity index 96% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLDataPrinter.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLDataPrinter.java index 7f9526b6..8502593c 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLDataPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLDataPrinter.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package de.atextor.ret.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.OWLDataComplementOf; import org.semanticweb.owlapi.model.OWLDataIntersectionOf; import org.semanticweb.owlapi.model.OWLDataOneOf; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLIndividualPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLIndividualPrinter.java similarity index 89% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLIndividualPrinter.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLIndividualPrinter.java index 2fe3e93c..1d7d055b 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLIndividualPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLIndividualPrinter.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package de.atextor.ret.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.OWLAnonymousIndividual; import org.semanticweb.owlapi.model.OWLIndividualVisitorEx; import org.semanticweb.owlapi.model.OWLNamedIndividual; @@ -27,7 +27,7 @@ * Serializes {@link org.semanticweb.owlapi.model.OWLIndividual}s into expressions */ public class OWLIndividualPrinter implements OWLIndividualVisitorEx { - MappingConfiguration mappingConfiguration; + final MappingConfiguration mappingConfiguration; public OWLIndividualPrinter( final MappingConfiguration mappingConfiguration ) { this.mappingConfiguration = mappingConfiguration; diff --git a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLPropertyExpressionPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLPropertyExpressionPrinter.java similarity index 94% rename from diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLPropertyExpressionPrinter.java rename to ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLPropertyExpressionPrinter.java index 23654d76..e375a07b 100644 --- a/diagram/src/main/java/de/atextor/owlcli/diagram/printers/OWLPropertyExpressionPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLPropertyExpressionPrinter.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.printers; +package de.atextor.ret.diagram.owl.printers; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.model.OWLAnnotationProperty; import org.semanticweb.owlapi.model.OWLDataProperty; import org.semanticweb.owlapi.model.OWLObjectInverseOf; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/DiagramGeneratorTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/DiagramGeneratorTest.java similarity index 74% rename from diagram/src/test/java/de/atextor/owlcli/diagram/diagram/DiagramGeneratorTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/DiagramGeneratorTest.java index 175e3d0e..6e31cc3e 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/DiagramGeneratorTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/DiagramGeneratorTest.java @@ -14,47 +14,47 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; -import de.atextor.owlcli.diagram.mappers.DefaultIdentifierMapper; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.IdentifierMapper; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.graph.node.Class; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.DataExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataProperty; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.DisjointUnion; +import de.atextor.ret.diagram.owl.graph.node.Disjointness; +import de.atextor.ret.diagram.owl.graph.node.Equality; +import de.atextor.ret.diagram.owl.graph.node.ExistentialRestriction; +import de.atextor.ret.diagram.owl.graph.node.Individual; +import de.atextor.ret.diagram.owl.graph.node.Inequality; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.Inverse; +import de.atextor.ret.diagram.owl.graph.node.Invisible; +import de.atextor.ret.diagram.owl.graph.node.Literal; +import de.atextor.ret.diagram.owl.graph.node.ObjectExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectProperty; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.PropertyChain; +import de.atextor.ret.diagram.owl.graph.node.PropertyMarker; +import de.atextor.ret.diagram.owl.graph.node.Self; +import de.atextor.ret.diagram.owl.graph.node.Union; +import de.atextor.ret.diagram.owl.graph.node.UniversalRestriction; +import de.atextor.ret.diagram.owl.graph.node.ValueRestriction; +import de.atextor.ret.diagram.owl.mappers.DefaultIdentifierMapper; +import de.atextor.ret.diagram.owl.mappers.DefaultMappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.IdentifierMapper; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import io.vavr.control.Try; import net.jqwik.api.Arbitraries; import net.jqwik.api.Arbitrary; @@ -72,7 +72,7 @@ import java.util.Set; public class DiagramGeneratorTest { - File workingDir = new File( System.getProperty( "user.dir" ) ); + final File workingDir = new File( System.getProperty( "user.dir" ) ); final Configuration configuration = Configuration.builder().build(); diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/GraphvizGeneratorTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/GraphvizGeneratorTest.java similarity index 80% rename from diagram/src/test/java/de/atextor/owlcli/diagram/diagram/GraphvizGeneratorTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/GraphvizGeneratorTest.java index 9d4866eb..20468a35 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/diagram/GraphvizGeneratorTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/GraphvizGeneratorTest.java @@ -14,39 +14,39 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.DisjointUnion; -import de.atextor.owlcli.diagram.graph.node.Disjointness; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.IRIReference; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.graph.node.Literal; -import de.atextor.owlcli.diagram.graph.node.ObjectExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.graph.node.Class; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.DataExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataProperty; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.DisjointUnion; +import de.atextor.ret.diagram.owl.graph.node.Disjointness; +import de.atextor.ret.diagram.owl.graph.node.ExistentialRestriction; +import de.atextor.ret.diagram.owl.graph.node.IRIReference; +import de.atextor.ret.diagram.owl.graph.node.Individual; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.Invisible; +import de.atextor.ret.diagram.owl.graph.node.Literal; +import de.atextor.ret.diagram.owl.graph.node.ObjectExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectProperty; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.PropertyChain; +import de.atextor.ret.diagram.owl.graph.node.Self; +import de.atextor.ret.diagram.owl.graph.node.Union; +import de.atextor.ret.diagram.owl.graph.node.UniversalRestriction; +import de.atextor.ret.diagram.owl.graph.node.ValueRestriction; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.IRI; @@ -133,7 +133,7 @@ private void testValueNode( final Node node ) { } @Test - void testNodeelementsTypeClass() { + void testNodeElementsTypeClass() { testNamedNode( new Class( from1, name1 ) ); } diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/MapperTestBase.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/MapperTestBase.java similarity index 92% rename from diagram/src/test/java/de/atextor/owlcli/diagram/MapperTestBase.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/MapperTestBase.java index 3b018f52..ca20f505 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/MapperTestBase.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/MapperTestBase.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.Invisible; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.Invisible; +import de.atextor.ret.diagram.owl.mappers.DefaultMappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.IRI; @@ -43,21 +43,28 @@ import static org.assertj.core.api.Fail.fail; public class MapperTestBase { - protected TestIdentifierMapper testIdentifierMapper = new TestIdentifierMapper(); - protected TestNameMapper testNameMapper = new TestNameMapper(); + protected final TestIdentifierMapper testIdentifierMapper = new TestIdentifierMapper(); + + protected final TestNameMapper testNameMapper = new TestNameMapper(); protected final Predicate hasDefaultArrow = edge -> edge.getType().equals( Edge.Type.DEFAULT_ARROW ); + protected final Predicate hasHollowArrow = edge -> edge.getType().equals( Edge.Type.HOLLOW_ARROW ); + protected final Predicate hasDashedArrow = edge -> edge.getType().equals( Edge.Type.DASHED_ARROW ); + protected final Predicate hasNoArrow = edge -> edge.getType().equals( Edge.Type.NO_ARROW ); + final Predicate hasDomainLabel = edge -> edge.view( Edge.Decorated.class ) .map( decoratedEdge -> decoratedEdge.getLabel().equals( Edge.Decorated.Label.DOMAIN ) ) .findFirst() .orElse( false ); + final Predicate hasRangeLabel = edge -> edge.view( Edge.Decorated.class ) .map( decoratedEdge -> decoratedEdge.getLabel().equals( Edge.Decorated.Label.RANGE ) ) .findFirst() .orElse( false ); + final Predicate hasFromBar = edge -> edge.getFrom().getId().getId().equals( "bar" ); protected MappingConfiguration createTestMappingConfiguration() { diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAnnotationObjectMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAnnotationObjectMapperTest.java similarity index 89% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLAnnotationObjectMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAnnotationObjectMapperTest.java index aae2f6e5..e5d2ffdc 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAnnotationObjectMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAnnotationObjectMapperTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package de.atextor.ret.diagram.owl; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.mappers.OWLAnnotationObjectMapper; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.mappers.OWLAnnotationObjectMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAxiomMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAxiomMapperTest.java similarity index 98% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLAxiomMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAxiomMapperTest.java index bd97f57a..7bb3b1d9 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLAxiomMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAxiomMapperTest.java @@ -14,22 +14,22 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.Equality; -import de.atextor.owlcli.diagram.graph.node.Inequality; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.Key; -import de.atextor.owlcli.diagram.graph.node.PropertyChain; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.mappers.IdentifierMapper; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLAxiomMapper; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.Equality; +import de.atextor.ret.diagram.owl.graph.node.Inequality; +import de.atextor.ret.diagram.owl.graph.node.Inverse; +import de.atextor.ret.diagram.owl.graph.node.Key; +import de.atextor.ret.diagram.owl.graph.node.PropertyChain; +import de.atextor.ret.diagram.owl.graph.node.PropertyMarker; +import de.atextor.ret.diagram.owl.mappers.IdentifierMapper; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.OWLAxiomMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.IRI; @@ -1027,6 +1027,7 @@ public void testOWLSubAnnotationPropertyOfAxiom() { @Test public void testOWLAnnotationPropertyRangeAxiom() { + // TODO } private void assertEquivalentResult( final Set result, final IRI fooIri, final IRI barIri, diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLClassExpressionMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLClassExpressionMapperTest.java similarity index 96% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLClassExpressionMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLClassExpressionMapperTest.java index b44f856c..ad871d00 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLClassExpressionMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLClassExpressionMapperTest.java @@ -14,29 +14,29 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.DataExactCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.DataMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ExistentialRestriction; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.ObjectMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedExactCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMaximalCardinality; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.Self; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.graph.node.UniversalRestriction; -import de.atextor.owlcli.diagram.graph.node.ValueRestriction; -import de.atextor.owlcli.diagram.mappers.OWLClassExpressionMapper; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Class; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.DataExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.DataMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ExistentialRestriction; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.ObjectMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedExactCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMaximalCardinality; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.Self; +import de.atextor.ret.diagram.owl.graph.node.Union; +import de.atextor.ret.diagram.owl.graph.node.UniversalRestriction; +import de.atextor.ret.diagram.owl.graph.node.ValueRestriction; +import de.atextor.ret.diagram.owl.mappers.OWLClassExpressionMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLClass; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLDataMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLDataMapperTest.java similarity index 94% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLDataMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLDataMapperTest.java index cd771ee8..6f787e4a 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLDataMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLDataMapperTest.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.ClosedClass; -import de.atextor.owlcli.diagram.graph.node.Complement; -import de.atextor.owlcli.diagram.graph.node.Datatype; -import de.atextor.owlcli.diagram.graph.node.Intersection; -import de.atextor.owlcli.diagram.graph.node.Union; -import de.atextor.owlcli.diagram.mappers.OWLDataMapper; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.ClosedClass; +import de.atextor.ret.diagram.owl.graph.node.Complement; +import de.atextor.ret.diagram.owl.graph.node.Datatype; +import de.atextor.ret.diagram.owl.graph.node.Intersection; +import de.atextor.ret.diagram.owl.graph.node.Union; +import de.atextor.ret.diagram.owl.mappers.OWLDataMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLDataComplementOf; @@ -234,10 +234,12 @@ public void testOWLDatatypeRestriction() { @Test public void testOWLFacetRestriction() { + // TODO } @Test public void testOWLDatatype() { + // TODO } @Test diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLEntityMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLEntityMapperTest.java similarity index 85% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLEntityMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLEntityMapperTest.java index 96eb57d7..ab0ca372 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLEntityMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLEntityMapperTest.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package de.atextor.ret.diagram.owl; -import de.atextor.owlcli.diagram.mappers.OWLEntityMapper; +import de.atextor.ret.diagram.owl.mappers.OWLEntityMapper; import org.junit.jupiter.api.Test; public class OWLEntityMapperTest extends MapperTestBase { @@ -24,25 +24,31 @@ public class OWLEntityMapperTest extends MapperTestBase { @Test public void testOWLClass() { + // TODO } @Test public void testOWLDatatype() { + // TODO } @Test public void testOWLNamedIndividual() { + // TODO } @Test public void testOWLObjectProperty() { + // TODO } @Test public void testOWLDataProperty() { + // TODO } @Test public void testOWLAnnotationProperty() { + // TODO } } diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLIndividualMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLIndividualMapperTest.java similarity index 90% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLIndividualMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLIndividualMapperTest.java index e4bdf3ce..cb806490 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLIndividualMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLIndividualMapperTest.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package de.atextor.ret.diagram.owl; -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLIndividualMapper; +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.node.Individual; +import de.atextor.ret.diagram.owl.mappers.DefaultMappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.OWLIndividualMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLOntologyMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLOntologyMapperTest.java similarity index 93% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLOntologyMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLOntologyMapperTest.java index f77aae27..bc8db013 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLOntologyMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLOntologyMapperTest.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.Class; -import de.atextor.owlcli.diagram.graph.node.Individual; -import de.atextor.owlcli.diagram.graph.node.PropertyMarker; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLOntologyMapper; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.Class; +import de.atextor.ret.diagram.owl.graph.node.Individual; +import de.atextor.ret.diagram.owl.graph.node.PropertyMarker; +import de.atextor.ret.diagram.owl.mappers.DefaultMappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.OWLOntologyMapper; import org.junit.jupiter.api.Test; import java.util.List; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLPropertyExpressionMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLPropertyExpressionMapperTest.java similarity index 90% rename from diagram/src/test/java/de/atextor/owlcli/diagram/OWLPropertyExpressionMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLPropertyExpressionMapperTest.java index 7951cc9e..d74520ae 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/OWLPropertyExpressionMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLPropertyExpressionMapperTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Graph; -import de.atextor.owlcli.diagram.graph.node.AnnotationProperty; -import de.atextor.owlcli.diagram.graph.node.DataProperty; -import de.atextor.owlcli.diagram.graph.node.Inverse; -import de.atextor.owlcli.diagram.graph.node.ObjectProperty; -import de.atextor.owlcli.diagram.mappers.OWLPropertyExpressionMapper; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Graph; +import de.atextor.ret.diagram.owl.graph.node.AnnotationProperty; +import de.atextor.ret.diagram.owl.graph.node.DataProperty; +import de.atextor.ret.diagram.owl.graph.node.Inverse; +import de.atextor.ret.diagram.owl.graph.node.ObjectProperty; +import de.atextor.ret.diagram.owl.mappers.OWLPropertyExpressionMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLAnnotationProperty; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/SWRLObjectMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/SWRLObjectMapperTest.java similarity index 96% rename from diagram/src/test/java/de/atextor/owlcli/diagram/SWRLObjectMapperTest.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/SWRLObjectMapperTest.java index 87c12e52..a5ee44a0 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/SWRLObjectMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/SWRLObjectMapperTest.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; - -import de.atextor.owlcli.diagram.graph.Edge; -import de.atextor.owlcli.diagram.graph.GraphElement; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.graph.node.ObjectQualifiedMinimalCardinality; -import de.atextor.owlcli.diagram.graph.node.Rule; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; -import de.atextor.owlcli.diagram.mappers.OWLAxiomMapper; +package de.atextor.ret.diagram.owl; + +import de.atextor.ret.diagram.owl.graph.Edge; +import de.atextor.ret.diagram.owl.graph.GraphElement; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.graph.node.ObjectQualifiedMinimalCardinality; +import de.atextor.ret.diagram.owl.graph.node.Rule; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.OWLAxiomMapper; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.SWRLRule; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/TestIdentifierMapper.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestIdentifierMapper.java similarity index 91% rename from diagram/src/test/java/de/atextor/owlcli/diagram/TestIdentifierMapper.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestIdentifierMapper.java index da076f41..a7f89634 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/TestIdentifierMapper.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestIdentifierMapper.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package de.atextor.ret.diagram.owl; -import de.atextor.owlcli.diagram.graph.Node; -import de.atextor.owlcli.diagram.mappers.IdentifierMapper; +import de.atextor.ret.diagram.owl.graph.Node; +import de.atextor.ret.diagram.owl.mappers.IdentifierMapper; import org.semanticweb.owlapi.model.IRI; import java.util.Stack; diff --git a/diagram/src/test/java/de/atextor/owlcli/diagram/TestNameMapper.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestNameMapper.java similarity index 91% rename from diagram/src/test/java/de/atextor/owlcli/diagram/TestNameMapper.java rename to ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestNameMapper.java index f8e987aa..759a6806 100644 --- a/diagram/src/test/java/de/atextor/owlcli/diagram/TestNameMapper.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestNameMapper.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package de.atextor.owlcli.diagram; +package de.atextor.ret.diagram.owl; -import de.atextor.owlcli.diagram.mappers.NameMapper; +import de.atextor.ret.diagram.owl.mappers.NameMapper; import org.semanticweb.owlapi.model.HasIRI; import org.semanticweb.owlapi.model.IRI; From c3fb1905fc2eb75105df327413e7cd6aa41fcf95 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Wed, 8 Nov 2023 05:39:17 +0100 Subject: [PATCH 147/280] Turn CLI module into Maven module --- cli/build.gradle | 204 ------------------ cli/settings.gradle | 18 -- ret-cli/pom.xml | 149 +++++++++++++ .../de/atextor/ret/cli}/AbstractCommand.java | 7 +- .../de/atextor/ret/cli}/ErrorMessage.java | 2 +- .../de/atextor/ret/cli}/LoggingMixin.java | 2 +- .../main/java/de/atextor/ret/cli}/OWLCLI.java | 3 +- .../java/de/atextor/ret/cli/OWLCLIConfig.java | 6 + .../ret/cli}/OWLCLIDiagramCommand.java | 23 +- .../atextor/ret/cli}/OWLCLIInferCommand.java | 18 +- .../atextor/ret/cli}/OWLCLIWriteCommand.java | 34 ++- ...module_SubsystemRegistryServiceLoader.java | 2 +- ..._riot_system_stream_JenaIOEnvironment.java | 2 +- ..._org_apache_jena_util_FileManagerImpl.java | 2 +- ...t_org_apache_jena_util_LocationMapper.java | 2 +- .../de.atextor/owlcli/jni-config.json | 0 .../de.atextor/owlcli/native-image.properties | 0 .../de.atextor/owlcli/proxy-config.json | 0 .../de.atextor/owlcli/reflect-config.json | 0 .../de.atextor/owlcli/resource-config.json | 0 .../owlcli/serialization-config.json | 0 .../ret/cli}/BinaryIntegrationTest.java | 2 +- .../CaptureSystemExitSecurityManager.java | 2 +- .../de/atextor/ret/cli}/CommandLineTest.java | 7 +- .../atextor/ret/cli}/DiagramCommandTest.java | 4 +- .../de/atextor/ret/cli}/MainClassRunner.java | 5 +- .../ret/cli}/ResourceArgumentsProvider.java | 4 +- .../ret/cli}/SystemExitCapturedException.java | 2 +- .../resources/asymmetric-objectproperty.ttl | 0 .../src/test/resources/class-assertion.ttl | 0 .../src/test/resources/data-intersection.ttl | 0 .../test/resources/dataproperty-assertion.ttl | 0 .../test/resources/dataproperty-domain.ttl | 0 .../src/test/resources/dataproperty-range.ttl | 0 .../test/resources/datarange-expression.ttl | 0 .../test/resources/datatype-definition.ttl | 0 .../test/resources/different-individuals.ttl | 0 .../src/test/resources/disjoint-classes.ttl | 0 .../resources/disjoint-dataproperties.ttl | 0 .../resources/disjoint-objectproperties.ttl | 0 .../src/test/resources/disjoint-union.ttl | 0 .../src/test/resources/equivalent-classes.ttl | 0 .../resources/equivalent-dataproperties.ttl | 0 .../resources/equivalent-objectproperties.ttl | 0 .../resources/functional-dataproperty.ttl | 0 .../resources/functional-objectproperty.ttl | 0 .../src/test/resources/has-key.ttl | 0 .../inverse-functional-objectproperty.ttl | 0 .../resources/inverse-objectproperties.ttl | 0 .../resources/irreflexive-objectproperty.ttl | 0 .../negative-dataproperty-assertion.ttl | 0 .../negative-objectproperty-assertion.ttl | 0 .../src/test/resources/object-complement.ttl | 0 .../test/resources/object-intersection.ttl | 0 .../src/test/resources/object-oneof.ttl | 0 .../src/test/resources/object-union.ttl | 0 .../resources/objectproperty-assertion.ttl | 0 .../test/resources/objectproperty-domain.ttl | 0 .../test/resources/objectproperty-range.ttl | 0 .../src/test/resources/property-chain.ttl | 0 .../resources/reflexive-objectproperty.ttl | 0 .../resources/restriction-allvaluesfrom.ttl | 0 .../restriction-data-allvaluesfrom.ttl | 0 .../restriction-data-exact-cardinality.ttl | 0 .../resources/restriction-data-hasvalue.ttl | 0 .../restriction-data-max-cardinality.ttl | 0 .../restriction-data-min-cardinality.ttl | 0 .../restriction-data-somevaluesfrom.ttl | 0 .../test/resources/restriction-has-self.ttl | 0 .../restriction-object-exact-cardinality.ttl | 0 .../resources/restriction-object-hasvalue.ttl | 0 .../restriction-object-max-cardinality.ttl | 0 ...ction-object-qualified-min-cardinality.ttl | 0 ...ion-object-unqualified-min-cardinality.ttl | 0 .../resources/restriction-somevaluesfrom.ttl | 0 .../src/test/resources/same-individuals.ttl | 0 .../test/resources/subannotationproperty.ttl | 0 .../src/test/resources/subclass.ttl | 0 .../src/test/resources/subdataproperty.ttl | 0 .../src/test/resources/subobjectproperty.ttl | 0 .../test/resources/swrl-rule-builtin-atom.ttl | 0 .../swrl-rule-class-atom-with-expression.ttl | 0 .../test/resources/swrl-rule-class-atom.ttl | 0 .../resources/swrl-rule-data-range-atom.ttl | 0 .../swrl-rule-object-property-atom.ttl | 0 .../resources/symmetric-objectproperty.ttl | 0 .../resources/transitive-objectproperty.ttl | 0 87 files changed, 229 insertions(+), 271 deletions(-) delete mode 100644 cli/build.gradle delete mode 100644 cli/settings.gradle create mode 100644 ret-cli/pom.xml rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/AbstractCommand.java (97%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/ErrorMessage.java (96%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/LoggingMixin.java (99%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/OWLCLI.java (98%) create mode 100644 ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/OWLCLIDiagramCommand.java (87%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/OWLCLIInferCommand.java (85%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/OWLCLIWriteCommand.java (93%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java (98%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java (96%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/substitution/Target_org_apache_jena_util_FileManagerImpl.java (96%) rename {cli/src/main/java/de/atextor/owlcli => ret-cli/src/main/java/de/atextor/ret/cli}/substitution/Target_org_apache_jena_util_LocationMapper.java (96%) rename {cli => ret-cli}/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json (100%) rename {cli => ret-cli}/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties (100%) rename {cli => ret-cli}/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json (100%) rename {cli => ret-cli}/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json (100%) rename {cli => ret-cli}/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json (100%) rename {cli => ret-cli}/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json (100%) rename {cli/src/integrationTest/java/de/atextor/owlcli => ret-cli/src/test/java/de/atextor/ret/cli}/BinaryIntegrationTest.java (99%) rename {cli/src/test/java/de/atextor/owlcli => ret-cli/src/test/java/de/atextor/ret/cli}/CaptureSystemExitSecurityManager.java (97%) rename {cli/src/test/java/de/atextor/owlcli => ret-cli/src/test/java/de/atextor/ret/cli}/CommandLineTest.java (87%) rename {cli/src/test/java/de/atextor/owlcli => ret-cli/src/test/java/de/atextor/ret/cli}/DiagramCommandTest.java (97%) rename {cli/src/test/java/de/atextor/owlcli => ret-cli/src/test/java/de/atextor/ret/cli}/MainClassRunner.java (92%) rename {cli/src/test/java/de/atextor/owlcli => ret-cli/src/test/java/de/atextor/ret/cli}/ResourceArgumentsProvider.java (96%) rename {cli/src/test/java/de/atextor/owlcli => ret-cli/src/test/java/de/atextor/ret/cli}/SystemExitCapturedException.java (96%) rename {cli => ret-cli}/src/test/resources/asymmetric-objectproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/class-assertion.ttl (100%) rename {cli => ret-cli}/src/test/resources/data-intersection.ttl (100%) rename {cli => ret-cli}/src/test/resources/dataproperty-assertion.ttl (100%) rename {cli => ret-cli}/src/test/resources/dataproperty-domain.ttl (100%) rename {cli => ret-cli}/src/test/resources/dataproperty-range.ttl (100%) rename {cli => ret-cli}/src/test/resources/datarange-expression.ttl (100%) rename {cli => ret-cli}/src/test/resources/datatype-definition.ttl (100%) rename {cli => ret-cli}/src/test/resources/different-individuals.ttl (100%) rename {cli => ret-cli}/src/test/resources/disjoint-classes.ttl (100%) rename {cli => ret-cli}/src/test/resources/disjoint-dataproperties.ttl (100%) rename {cli => ret-cli}/src/test/resources/disjoint-objectproperties.ttl (100%) rename {cli => ret-cli}/src/test/resources/disjoint-union.ttl (100%) rename {cli => ret-cli}/src/test/resources/equivalent-classes.ttl (100%) rename {cli => ret-cli}/src/test/resources/equivalent-dataproperties.ttl (100%) rename {cli => ret-cli}/src/test/resources/equivalent-objectproperties.ttl (100%) rename {cli => ret-cli}/src/test/resources/functional-dataproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/functional-objectproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/has-key.ttl (100%) rename {cli => ret-cli}/src/test/resources/inverse-functional-objectproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/inverse-objectproperties.ttl (100%) rename {cli => ret-cli}/src/test/resources/irreflexive-objectproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/negative-dataproperty-assertion.ttl (100%) rename {cli => ret-cli}/src/test/resources/negative-objectproperty-assertion.ttl (100%) rename {cli => ret-cli}/src/test/resources/object-complement.ttl (100%) rename {cli => ret-cli}/src/test/resources/object-intersection.ttl (100%) rename {cli => ret-cli}/src/test/resources/object-oneof.ttl (100%) rename {cli => ret-cli}/src/test/resources/object-union.ttl (100%) rename {cli => ret-cli}/src/test/resources/objectproperty-assertion.ttl (100%) rename {cli => ret-cli}/src/test/resources/objectproperty-domain.ttl (100%) rename {cli => ret-cli}/src/test/resources/objectproperty-range.ttl (100%) rename {cli => ret-cli}/src/test/resources/property-chain.ttl (100%) rename {cli => ret-cli}/src/test/resources/reflexive-objectproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-allvaluesfrom.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-data-allvaluesfrom.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-data-exact-cardinality.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-data-hasvalue.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-data-max-cardinality.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-data-min-cardinality.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-data-somevaluesfrom.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-has-self.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-object-exact-cardinality.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-object-hasvalue.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-object-max-cardinality.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-object-qualified-min-cardinality.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-object-unqualified-min-cardinality.ttl (100%) rename {cli => ret-cli}/src/test/resources/restriction-somevaluesfrom.ttl (100%) rename {cli => ret-cli}/src/test/resources/same-individuals.ttl (100%) rename {cli => ret-cli}/src/test/resources/subannotationproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/subclass.ttl (100%) rename {cli => ret-cli}/src/test/resources/subdataproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/subobjectproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/swrl-rule-builtin-atom.ttl (100%) rename {cli => ret-cli}/src/test/resources/swrl-rule-class-atom-with-expression.ttl (100%) rename {cli => ret-cli}/src/test/resources/swrl-rule-class-atom.ttl (100%) rename {cli => ret-cli}/src/test/resources/swrl-rule-data-range-atom.ttl (100%) rename {cli => ret-cli}/src/test/resources/swrl-rule-object-property-atom.ttl (100%) rename {cli => ret-cli}/src/test/resources/symmetric-objectproperty.ttl (100%) rename {cli => ret-cli}/src/test/resources/transitive-objectproperty.ttl (100%) diff --git a/cli/build.gradle b/cli/build.gradle deleted file mode 100644 index d4ec8662..00000000 --- a/cli/build.gradle +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import org.apache.tools.ant.taskdefs.condition.Os - -plugins { - id 'java' - id 'application' - id 'jacoco' - id 'com.github.johnrengelman.shadow' - id 'io.freefair.lombok' - id 'com.adarshr.test-logger' -} - -repositories { - maven { url 'https://jitpack.io' } -} - -configurations { - integrationTestImplementation.extendsFrom implementation - integrationTestRuntimeOnly.extendsFrom runtimeOnly -} - -apply from: file("${rootDir}/dependencies.gradle") -dependencies { - implementation project(':diagram') - implementation project(':write') - implementation project(':infer') - implementation(deps.owlapi) { - exclude group: 'org.slf4j', module: 'slf4j-simple' - } - implementation(deps.jena_core) - implementation(deps.jena_arq) - implementation(deps.turtle_formatter) - implementation(deps.vavr) - implementation(deps.picocli) - implementation(deps.logback) - annotationProcessor(deps.picocli_codegen) - - // Override transitive dependency versions due to features - implementation(deps.caffeine) - - // Override transitive dependency versions due to vulns - implementation(deps.guava) - implementation(deps.jackson_databind) - implementation(deps.httpclient) - implementation(deps.commons_codec) - - // To support GraalVM substitution classes - compileOnly(deps.svm) - - // Test - testImplementation(deps.junit_jupiter_api) - testImplementation(deps.junit_jupiter_params) - testImplementation(deps.commons_io) - testImplementation(deps.assertj) - testImplementation(deps.classgraph) - testRuntimeOnly(deps.junit_jupiter_engine) - - // Integration test - integrationTestImplementation(deps.junit_jupiter_api) - integrationTestImplementation(deps.junit_jupiter_params) - integrationTestImplementation(deps.assertj) - integrationTestImplementation(deps.classgraph) - integrationTestRuntimeOnly(deps.junit_jupiter_engine) -} - -configurations.all { - exclude group: "org.eclipse.rdf4j", module: "rdf4j-model" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-api" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-languages" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-datatypes" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-binary" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-n3" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-nquads" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-ntriples" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-rdfjson" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-jsonld" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-rdfxml" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-trix" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-trig" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-rio-turtle" - exclude group: "org.eclipse.rdf4j", module: "rdf4j-util" -} - -shadowJar { - archiveBaseName = 'owl-cli' - archiveClassifier = null -} - -def nativeImageBinary = Os.isFamily(Os.FAMILY_WINDOWS) ? file("${homeDir}/.sdkman/candidates/java/current/lib/svm/bin/native-image") : file("${homeDir}/.sdkman/candidates/java/17.0.8-graal/lib/svm/bin/native-image") -def nativeImageArgs = ['--verbose', '-jar', "${buildDir}/libs/owl-cli-${version}.jar", "${buildDir}/bin/owl"] -task nativeImage(type: Exec, dependsOn: "shadowJar") { - doFirst { - println nativeImageArgs.join(' ') - } - executable nativeImageBinary - args nativeImageArgs - inputs.file file("${buildDir}/libs/owl-cli-${version}.jar") - outputs.file file("${buildDir}/bin/owl") -} - -def appConfigClass = "OWLCLIConfig" -def genSrc = "${project.projectDir}/src/generated/java" -def genPackage = "${genSrc}/de/atextor/owlcli" -def genAppConfig = "${genPackage}/${appConfigClass}.java" -task generateStaticProperties() { - doLast { - file("${genPackage}").mkdirs() - file("${genAppConfig}").text = """/* Generated file, do not change */ -package de.atextor.owlcli; - -public class ${appConfigClass} { - public static final String VERSION = "${version}"; - public static final String BUILD_DATE = "${new Date().format("yyyy-MM-dd HH:mm:ss")}"; -} -""" - } -} - -tasks.register("integrationTest", Test) { - description = 'Runs integration tests.' - group = 'verification' - outputs.upToDateWhen { false } - testClassesDirs = sourceSets.integrationTest.output.classesDirs - classpath = sourceSets.integrationTest.runtimeClasspath - dependsOn shadowJar - shouldRunAfter nativeImage - onlyIf { project(':cli').file('build/bin/owl').exists() } - - testLogging { - showStandardStreams = true - } -} - -sourceSets { - generated { - java.srcDir "${genSrc}" - } - main { - compileClasspath += sourceSets.generated.output - } - integrationTest { - compileClasspath += sourceSets.main.output + sourceSets.test.output - runtimeClasspath += sourceSets.main.output + sourceSets.test.output - } -} - -compileJava { - sourceCompatibility = 17 - targetCompatibility = 17 - dependsOn(generateStaticProperties) -} - -compileTestJava { - sourceCompatibility = 17 - targetCompatibility = 17 -} - -test { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } - - testLogging { - showStandardStreams = true - } -} - -integrationTest { - useJUnitPlatform() - maxHeapSize = '1G' - ignoreFailures = false - failFast = true - - filter { - includeTestsMatching "*Test" - } - - testLogging { - showStandardStreams = true - } - - systemProperty "owlBinary", project(':cli').file('build/bin/owl').getCanonicalPath() -} - -mainClassName = 'de.atextor.owlcli.OWLCLI' diff --git a/cli/settings.gradle b/cli/settings.gradle deleted file mode 100644 index 63a2731b..00000000 --- a/cli/settings.gradle +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -rootProject.name = 'cli' -include ':diagram' diff --git a/ret-cli/pom.xml b/ret-cli/pom.xml new file mode 100644 index 00000000..74ef57c7 --- /dev/null +++ b/ret-cli/pom.xml @@ -0,0 +1,149 @@ + + + + ret + de.atextor.ret + 1.0-SNAPSHOT + + 4.0.0 + + ret-cli + + + 17 + 17 + UTF-8 + + + + + + de.atextor.ret + ret-diagram-owl + + + de.atextor.ret + ret-infer + + + de.atextor.ret + ret-write + + + + + + + + + + + + + + + + + + + + + + + com.github.ben-manes.caffeine + caffeine + + + commons-codec + commons-codec + + + com.google.guava + guava + + + com.fasterxml.jackson.core + jackson-databind + + + ch.qos.logback + logback-classic + + + info.picocli + picocli + + + de.atextor + turtle-formatter + + + + + org.graalvm.nativeimage + svm + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.assertj + assertj-core + test + + + commons-io + commons-io + test + + + io.github.classgraph + classgraph + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin-version} + + + + info.picocli + picocli-codegen + ${picocli-version} + + + + -Aproject=${project.groupId}/${project.artifactId} + --add-exports + java.desktop/sun.awt=ALL-UNNAMED + --add-exports + java.desktop/sun.font=ALL-UNNAMED + + true + + + + + + \ No newline at end of file diff --git a/cli/src/main/java/de/atextor/owlcli/AbstractCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java similarity index 97% rename from cli/src/main/java/de/atextor/owlcli/AbstractCommand.java rename to ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java index e277c314..17d62017 100644 --- a/cli/src/main/java/de/atextor/owlcli/AbstractCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import com.google.common.collect.ImmutableSet; import io.vavr.control.Try; @@ -66,7 +66,7 @@ protected Try openOutput( final @Nonnull String input, final Strin } if ( input.equals( "-" ) ) { - // Input is stdin, outout is not given -> write to stdout + // Input is stdin, output is not given -> write to stdout return Try.success( System.out ); } @@ -116,7 +116,8 @@ protected OWLOntologyManager createOWLOntologyManager() { .add( new OWLOntologyFactoryImpl( new NonConcurrentOWLOntologyBuilder() ) ) .build(); - final Set storerFactories = ImmutableSet.builder() + final Set storerFactories = + ImmutableSet.builder() .add( new org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory() ) .add( new org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory() ) .add( new org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory() ) diff --git a/cli/src/main/java/de/atextor/owlcli/ErrorMessage.java b/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java similarity index 96% rename from cli/src/main/java/de/atextor/owlcli/ErrorMessage.java rename to ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java index 309accc2..5016b75b 100644 --- a/cli/src/main/java/de/atextor/owlcli/ErrorMessage.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; public class ErrorMessage extends Exception { private static final long serialVersionUID = 5086560337386407192L; diff --git a/cli/src/main/java/de/atextor/owlcli/LoggingMixin.java b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java similarity index 99% rename from cli/src/main/java/de/atextor/owlcli/LoggingMixin.java rename to ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java index b29cf63e..acce383d 100644 --- a/cli/src/main/java/de/atextor/owlcli/LoggingMixin.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLI.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java similarity index 98% rename from cli/src/main/java/de/atextor/owlcli/OWLCLI.java rename to ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java index 7e776b11..b2e14e6e 100644 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLI.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java @@ -14,11 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import ch.qos.logback.classic.Level; import io.vavr.collection.List; -import org.apache.jena.sys.JenaSystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java new file mode 100644 index 00000000..f6bc010f --- /dev/null +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java @@ -0,0 +1,6 @@ +package de.atextor.ret.cli; + +public class OWLCLIConfig { + public static final String VERSION = ""; + public static final String BUILD_DATE = ""; +} diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLIDiagramCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java similarity index 87% rename from cli/src/main/java/de/atextor/owlcli/OWLCLIDiagramCommand.java rename to ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java index ced260b9..3b1582e3 100644 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLIDiagramCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; -import de.atextor.owlcli.diagram.diagram.Configuration; -import de.atextor.owlcli.diagram.diagram.DiagramGenerator; -import de.atextor.owlcli.diagram.diagram.GraphvizDocument; -import de.atextor.owlcli.diagram.mappers.DefaultMappingConfiguration; -import de.atextor.owlcli.diagram.mappers.MappingConfiguration; +import de.atextor.ret.diagram.owl.Configuration; +import de.atextor.ret.diagram.owl.DiagramGenerator; +import de.atextor.ret.diagram.owl.GraphvizDocument; +import de.atextor.ret.diagram.owl.mappers.DefaultMappingConfiguration; +import de.atextor.ret.diagram.owl.mappers.MappingConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; @@ -41,38 +41,49 @@ public class OWLCLIDiagramCommand extends AbstractCommand implements Runnable { @CommandLine.Mixin LoggingMixin loggingMixin; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--fontname" }, description = "The font to use (Default: ${DEFAULT-VALUE})" ) private String fontname = config.fontname; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--fontsize" }, description = "Default font size (Default: ${DEFAULT-VALUE})" ) private int fontsize = config.fontsize; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--nodefontname" }, description = "Font for nodes (Default: ${DEFAULT-VALUE})" ) private String nodeFontName = config.nodeFontname; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--nodefontsize" }, description = "Font size for nodes (Default: ${DEFAULT-VALUE})" ) private int nodeFontsize = config.nodeFontsize; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--nodeshape" }, description = "Node shape (Default: ${DEFAULT-VALUE})" ) private String nodeShape = config.nodeShape; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--nodemargin" }, description = "Node margin (Default: ${DEFAULT-VALUE})" ) private String nodeMargin = config.nodeMargin; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--nodestyle" }, description = "Node style (Default: ${DEFAULT-VALUE})" ) private String nodeStyle = config.nodeStyle; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--format" }, description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format format = config.format; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--direction" }, description = "Diagram layout direction, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.LayoutDirection layoutDirection = config.layoutDirection; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--dotbinary" }, description = "Path to dot binary (Default: ${DEFAULT-VALUE})" ) private String dotBinary = config.dotBinary; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--fgcolor" }, description = "Foreground color (Default: ${DEFAULT-VALUE})" ) private String fgColor = config.fgColor; diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLIInferCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java similarity index 85% rename from cli/src/main/java/de/atextor/owlcli/OWLCLIInferCommand.java rename to ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java index c5511cee..0f841f00 100644 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLIInferCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java @@ -14,28 +14,16 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; -import de.atextor.owlcli.infer.Configuration; -import de.atextor.owlcli.infer.Inferrer; -import de.atextor.turtle.formatter.FormattingStyle; -import org.apache.jena.rdf.model.Property; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.ResourceFactory; +import de.atextor.ret.infer.Configuration; +import de.atextor.ret.infer.Inferrer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; import java.net.MalformedURLException; -import java.net.URI; import java.net.URL; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.Map; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.stream.Collectors; @CommandLine.Command( name = "infer", description = "Runs an OWL reasoner on an ontology", diff --git a/cli/src/main/java/de/atextor/owlcli/OWLCLIWriteCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java similarity index 93% rename from cli/src/main/java/de/atextor/owlcli/OWLCLIWriteCommand.java rename to ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java index 2570a2bb..76141f8d 100644 --- a/cli/src/main/java/de/atextor/owlcli/OWLCLIWriteCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; -import de.atextor.owlcli.write.Configuration; -import de.atextor.owlcli.write.RdfWriter; +import de.atextor.ret.write.Configuration; +import de.atextor.ret.write.RdfWriter; import de.atextor.turtle.formatter.FormattingStyle; import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.RDFNode; @@ -57,96 +57,119 @@ public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { @CommandLine.Mixin LoggingMixin loggingMixin; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "-o", "--output" }, description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format outputFormat = config.outputFormat; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "-i", "--input" }, description = "Input file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format inputFormat = config.inputFormat; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "-p", "--prefix" }, description = "Prefix to add as @prefix when used.", mapFallbackValue = fallbackUri ) private Map prefixMap = new HashMap<>(); + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--prefixAlign" }, description = "Alignment of @prefix statements, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Alignment alignPrefixes = FormattingStyle.DEFAULT.alignPrefixes; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--encoding" }, description = "Output encoding, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Charset encoding = FormattingStyle.DEFAULT.charset; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--doubleFormat" }, description = "Defines how double numbers are formatted (Default: ${DEFAULT-VALUE})" ) private String doubleFormatPattern = ( (DecimalFormat) FormattingStyle.DEFAULT.doubleFormat ).toPattern(); + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--endOfLine" }, description = "End of line style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.EndOfLineStyle endOfLineStyle = FormattingStyle.DEFAULT.endOfLine; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--indent" }, description = "Indent style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.IndentStyle indentStyle = FormattingStyle.DEFAULT.indentStyle; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--firstPredicateInNewLine" }, description = "Write first predicate in new line of block (Default: ${DEFAULT-VALUE})" ) private boolean firstPredicateInNewLine = FormattingStyle.DEFAULT.firstPredicateInNewLine; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--writeRdfType" }, description = "Write 'rdf:type' instead of 'a' (Default: ${DEFAULT-VALUE})" ) private boolean writeRdfType = !FormattingStyle.DEFAULT.useAForRdfType; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--useCommaByDefault" }, description = "Use commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private boolean useCommaByDefault = FormattingStyle.DEFAULT.useCommaByDefault; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--commaForPredicate" }, description = "A set of predicates that, when used multiple times, are separated by commas, even when " + "useCommaByDefault is false (Default: ${DEFAULT-VALUE})" ) private Set commaForPredicate = FormattingStyle.DEFAULT.commaForPredicate; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--noCommaForPredicate" }, description = "Use no commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private Set noCommaForPredicate = FormattingStyle.DEFAULT.noCommaForPredicate; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--useLongLiterals" }, description = "Use long form for literals where possible (Default: ${DEFAULT-VALUE})" ) private boolean useLongLiterals = !FormattingStyle.DEFAULT.useShortLiterals; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--alignObjects" }, description = "Align objects for same predicates (Default: ${DEFAULT-VALUE})" ) private boolean alignObjects = FormattingStyle.DEFAULT.alignObjects; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--alignPredicates" }, description = "Align predicates for same subjects (Default: ${DEFAULT-VALUE})" ) private boolean alignPredicates = FormattingStyle.DEFAULT.alignPredicates; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--continuationIndentSize" }, description = "Indentation size after forced line wraps (Default: ${DEFAULT-VALUE})" ) private int continuationIndentSize = FormattingStyle.DEFAULT.continuationIndentSize; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--doNotInsertFinalNewline" }, description = "Do not insert newline at end of file (Default: ${DEFAULT-VALUE})" ) private boolean doNotInsertFinalNewline = !FormattingStyle.DEFAULT.insertFinalNewline; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--indentSize" }, description = "Indentation size in spaces (Default: ${DEFAULT-VALUE})" ) private int indentSize = FormattingStyle.DEFAULT.indentSize; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--keepUnusedPrefixes" }, description = "Keeps prefixes that are not part of any statement (Default: ${DEFAULT-VALUE})" ) private boolean keepUnusedPrefixes = FormattingStyle.DEFAULT.keepUnusedPrefixes; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--prefixOrder" }, description = "Sort order for prefixes (Default: ${DEFAULT-VALUE})" ) private List prefixOrder = FormattingStyle.DEFAULT.prefixOrder; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--subjectOrder" }, description = "Sort order for subjects by type (Default: ${DEFAULT-VALUE})" ) private List subjectOrder = FormattingStyle.DEFAULT.subjectOrder; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--predicateOrder" }, description = "Sort order for predicates (Default: ${DEFAULT-VALUE})" ) private List predicateOrder = FormattingStyle.DEFAULT.predicateOrder; @@ -155,6 +178,7 @@ public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { description = "Sort order for objects (Default: ${DEFAULT-VALUE})" ) private List objectOrder = FormattingStyle.DEFAULT.objectOrder; + @SuppressWarnings( "CanBeFinal" ) @CommandLine.Option( names = { "--anonymousNodeIdPattern" }, description = "Name pattern for blank node IDs (Default: ${DEFAULT-VALUE})" ) private String anonymousNodeIdPattern = @@ -262,13 +286,13 @@ private BiFunction buildAnonymousNodeIdGenerator( fin private static class NumberFormatConverter implements CommandLine.ITypeConverter { @Override - public NumberFormat convert( final String value ) throws Exception { + public NumberFormat convert( final String value ) { return new DecimalFormat( value ); } } private abstract class AbstractResourceConverter { - protected String buildResourceUri( final String resourceUri ) throws Exception { + protected String buildResourceUri( final String resourceUri ) { for ( final Map.Entry entry : prefixMap.entrySet() ) { final URI uri = wellKnownUriByPrefixOrElse( entry.getKey(), entry.getValue() ); if ( resourceUri.startsWith( entry.getKey() ) ) { diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java similarity index 98% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java rename to ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java index 7b6bed2e..c889617a 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package de.atextor.ret.cli.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.Substitute; diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java similarity index 96% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java rename to ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java index f88ef7fa..2d73eed7 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package de.atextor.ret.cli.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_FileManagerImpl.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java similarity index 96% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_FileManagerImpl.java rename to ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java index 41886592..d7efdcc2 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_FileManagerImpl.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package de.atextor.ret.cli.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.Substitute; diff --git a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_LocationMapper.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_LocationMapper.java similarity index 96% rename from cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_LocationMapper.java rename to ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_LocationMapper.java index 5565add4..9408c357 100644 --- a/cli/src/main/java/de/atextor/owlcli/substitution/Target_org_apache_jena_util_LocationMapper.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_LocationMapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli.substitution; +package de.atextor.ret.cli.substitution; import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json similarity index 100% rename from cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json rename to ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/jni-config.json diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties similarity index 100% rename from cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties rename to ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json similarity index 100% rename from cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json rename to ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/proxy-config.json diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json similarity index 100% rename from cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json rename to ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json similarity index 100% rename from cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json rename to ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/resource-config.json diff --git a/cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json similarity index 100% rename from cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json rename to ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/serialization-config.json diff --git a/cli/src/integrationTest/java/de/atextor/owlcli/BinaryIntegrationTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java similarity index 99% rename from cli/src/integrationTest/java/de/atextor/owlcli/BinaryIntegrationTest.java rename to ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java index 0f3a6685..fd5d77aa 100644 --- a/cli/src/integrationTest/java/de/atextor/owlcli/BinaryIntegrationTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; diff --git a/cli/src/test/java/de/atextor/owlcli/CaptureSystemExitSecurityManager.java b/ret-cli/src/test/java/de/atextor/ret/cli/CaptureSystemExitSecurityManager.java similarity index 97% rename from cli/src/test/java/de/atextor/owlcli/CaptureSystemExitSecurityManager.java rename to ret-cli/src/test/java/de/atextor/ret/cli/CaptureSystemExitSecurityManager.java index b9d9f39c..10db2538 100644 --- a/cli/src/test/java/de/atextor/owlcli/CaptureSystemExitSecurityManager.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/CaptureSystemExitSecurityManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import java.security.Permission; diff --git a/cli/src/test/java/de/atextor/owlcli/CommandLineTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java similarity index 87% rename from cli/src/test/java/de/atextor/owlcli/CommandLineTest.java rename to ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java index fa6fd05e..5f0c5344 100644 --- a/cli/src/test/java/de/atextor/owlcli/CommandLineTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import org.junit.jupiter.api.Test; -import static de.atextor.owlcli.MainClassRunner.run; +import static de.atextor.ret.cli.MainClassRunner.run; import static org.assertj.core.api.Assertions.assertThat; public class CommandLineTest { @@ -44,7 +44,8 @@ public void testHelp() { @Test public void testInvalidArguments() { - final Runnable command = () -> OWLCLI.main( new String[]{ "definitelynotavalidargument" } ); + @SuppressWarnings( "SpellCheckingInspection" ) final Runnable command = () -> OWLCLI.main( new String[]{ + "definitelynotavalidargument" } ); final MainClassRunner.ExecutionResult result = run( command ); assertThat( result.exitStatus() ).isEqualTo( 1 ); diff --git a/cli/src/test/java/de/atextor/owlcli/DiagramCommandTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/DiagramCommandTest.java similarity index 97% rename from cli/src/test/java/de/atextor/owlcli/DiagramCommandTest.java rename to ret-cli/src/test/java/de/atextor/ret/cli/DiagramCommandTest.java index d0a511b8..6d8895f4 100644 --- a/cli/src/test/java/de/atextor/owlcli/DiagramCommandTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/DiagramCommandTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.Test; @@ -27,7 +27,7 @@ import java.nio.file.Files; import java.nio.file.Path; -import static de.atextor.owlcli.MainClassRunner.run; +import static de.atextor.ret.cli.MainClassRunner.run; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; diff --git a/cli/src/test/java/de/atextor/owlcli/MainClassRunner.java b/ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java similarity index 92% rename from cli/src/test/java/de/atextor/owlcli/MainClassRunner.java rename to ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java index d9c1b7b9..a2851827 100644 --- a/cli/src/test/java/de/atextor/owlcli/MainClassRunner.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -25,7 +25,8 @@ record ExecutionResult(int exitStatus, String stdOut, String stdErr) { /** * This method uses {@link System#getSecurityManager()} and {@link System#setSecurityManager(SecurityManager)} that - * are deprecated as of Java 17. However, until https://bugs.openjdk.java.net/browse/JDK-8199704 is addressed, + * are deprecated as of Java 17. However, until + * JDK-8199704 is addressed, * we have still to rely on it. * * @param runnable the runnable to execute diff --git a/cli/src/test/java/de/atextor/owlcli/ResourceArgumentsProvider.java b/ret-cli/src/test/java/de/atextor/ret/cli/ResourceArgumentsProvider.java similarity index 96% rename from cli/src/test/java/de/atextor/owlcli/ResourceArgumentsProvider.java rename to ret-cli/src/test/java/de/atextor/ret/cli/ResourceArgumentsProvider.java index 9e8972d6..0bdb4cc5 100644 --- a/cli/src/test/java/de/atextor/owlcli/ResourceArgumentsProvider.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/ResourceArgumentsProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; import io.github.classgraph.ClassGraph; import org.junit.jupiter.api.extension.ExtensionContext; @@ -37,7 +37,7 @@ public Stream provideArguments( final ExtensionContext cont } public static class FilenameArguments implements Arguments { - String filename; + final String filename; public FilenameArguments( final String filename ) { this.filename = filename; diff --git a/cli/src/test/java/de/atextor/owlcli/SystemExitCapturedException.java b/ret-cli/src/test/java/de/atextor/ret/cli/SystemExitCapturedException.java similarity index 96% rename from cli/src/test/java/de/atextor/owlcli/SystemExitCapturedException.java rename to ret-cli/src/test/java/de/atextor/ret/cli/SystemExitCapturedException.java index 8d9fbf2a..9d9ff912 100644 --- a/cli/src/test/java/de/atextor/owlcli/SystemExitCapturedException.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/SystemExitCapturedException.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.owlcli; +package de.atextor.ret.cli; public class SystemExitCapturedException extends RuntimeException { private static final long serialVersionUID = 6080552325336609875L; diff --git a/cli/src/test/resources/asymmetric-objectproperty.ttl b/ret-cli/src/test/resources/asymmetric-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/asymmetric-objectproperty.ttl rename to ret-cli/src/test/resources/asymmetric-objectproperty.ttl diff --git a/cli/src/test/resources/class-assertion.ttl b/ret-cli/src/test/resources/class-assertion.ttl similarity index 100% rename from cli/src/test/resources/class-assertion.ttl rename to ret-cli/src/test/resources/class-assertion.ttl diff --git a/cli/src/test/resources/data-intersection.ttl b/ret-cli/src/test/resources/data-intersection.ttl similarity index 100% rename from cli/src/test/resources/data-intersection.ttl rename to ret-cli/src/test/resources/data-intersection.ttl diff --git a/cli/src/test/resources/dataproperty-assertion.ttl b/ret-cli/src/test/resources/dataproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/dataproperty-assertion.ttl rename to ret-cli/src/test/resources/dataproperty-assertion.ttl diff --git a/cli/src/test/resources/dataproperty-domain.ttl b/ret-cli/src/test/resources/dataproperty-domain.ttl similarity index 100% rename from cli/src/test/resources/dataproperty-domain.ttl rename to ret-cli/src/test/resources/dataproperty-domain.ttl diff --git a/cli/src/test/resources/dataproperty-range.ttl b/ret-cli/src/test/resources/dataproperty-range.ttl similarity index 100% rename from cli/src/test/resources/dataproperty-range.ttl rename to ret-cli/src/test/resources/dataproperty-range.ttl diff --git a/cli/src/test/resources/datarange-expression.ttl b/ret-cli/src/test/resources/datarange-expression.ttl similarity index 100% rename from cli/src/test/resources/datarange-expression.ttl rename to ret-cli/src/test/resources/datarange-expression.ttl diff --git a/cli/src/test/resources/datatype-definition.ttl b/ret-cli/src/test/resources/datatype-definition.ttl similarity index 100% rename from cli/src/test/resources/datatype-definition.ttl rename to ret-cli/src/test/resources/datatype-definition.ttl diff --git a/cli/src/test/resources/different-individuals.ttl b/ret-cli/src/test/resources/different-individuals.ttl similarity index 100% rename from cli/src/test/resources/different-individuals.ttl rename to ret-cli/src/test/resources/different-individuals.ttl diff --git a/cli/src/test/resources/disjoint-classes.ttl b/ret-cli/src/test/resources/disjoint-classes.ttl similarity index 100% rename from cli/src/test/resources/disjoint-classes.ttl rename to ret-cli/src/test/resources/disjoint-classes.ttl diff --git a/cli/src/test/resources/disjoint-dataproperties.ttl b/ret-cli/src/test/resources/disjoint-dataproperties.ttl similarity index 100% rename from cli/src/test/resources/disjoint-dataproperties.ttl rename to ret-cli/src/test/resources/disjoint-dataproperties.ttl diff --git a/cli/src/test/resources/disjoint-objectproperties.ttl b/ret-cli/src/test/resources/disjoint-objectproperties.ttl similarity index 100% rename from cli/src/test/resources/disjoint-objectproperties.ttl rename to ret-cli/src/test/resources/disjoint-objectproperties.ttl diff --git a/cli/src/test/resources/disjoint-union.ttl b/ret-cli/src/test/resources/disjoint-union.ttl similarity index 100% rename from cli/src/test/resources/disjoint-union.ttl rename to ret-cli/src/test/resources/disjoint-union.ttl diff --git a/cli/src/test/resources/equivalent-classes.ttl b/ret-cli/src/test/resources/equivalent-classes.ttl similarity index 100% rename from cli/src/test/resources/equivalent-classes.ttl rename to ret-cli/src/test/resources/equivalent-classes.ttl diff --git a/cli/src/test/resources/equivalent-dataproperties.ttl b/ret-cli/src/test/resources/equivalent-dataproperties.ttl similarity index 100% rename from cli/src/test/resources/equivalent-dataproperties.ttl rename to ret-cli/src/test/resources/equivalent-dataproperties.ttl diff --git a/cli/src/test/resources/equivalent-objectproperties.ttl b/ret-cli/src/test/resources/equivalent-objectproperties.ttl similarity index 100% rename from cli/src/test/resources/equivalent-objectproperties.ttl rename to ret-cli/src/test/resources/equivalent-objectproperties.ttl diff --git a/cli/src/test/resources/functional-dataproperty.ttl b/ret-cli/src/test/resources/functional-dataproperty.ttl similarity index 100% rename from cli/src/test/resources/functional-dataproperty.ttl rename to ret-cli/src/test/resources/functional-dataproperty.ttl diff --git a/cli/src/test/resources/functional-objectproperty.ttl b/ret-cli/src/test/resources/functional-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/functional-objectproperty.ttl rename to ret-cli/src/test/resources/functional-objectproperty.ttl diff --git a/cli/src/test/resources/has-key.ttl b/ret-cli/src/test/resources/has-key.ttl similarity index 100% rename from cli/src/test/resources/has-key.ttl rename to ret-cli/src/test/resources/has-key.ttl diff --git a/cli/src/test/resources/inverse-functional-objectproperty.ttl b/ret-cli/src/test/resources/inverse-functional-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/inverse-functional-objectproperty.ttl rename to ret-cli/src/test/resources/inverse-functional-objectproperty.ttl diff --git a/cli/src/test/resources/inverse-objectproperties.ttl b/ret-cli/src/test/resources/inverse-objectproperties.ttl similarity index 100% rename from cli/src/test/resources/inverse-objectproperties.ttl rename to ret-cli/src/test/resources/inverse-objectproperties.ttl diff --git a/cli/src/test/resources/irreflexive-objectproperty.ttl b/ret-cli/src/test/resources/irreflexive-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/irreflexive-objectproperty.ttl rename to ret-cli/src/test/resources/irreflexive-objectproperty.ttl diff --git a/cli/src/test/resources/negative-dataproperty-assertion.ttl b/ret-cli/src/test/resources/negative-dataproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/negative-dataproperty-assertion.ttl rename to ret-cli/src/test/resources/negative-dataproperty-assertion.ttl diff --git a/cli/src/test/resources/negative-objectproperty-assertion.ttl b/ret-cli/src/test/resources/negative-objectproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/negative-objectproperty-assertion.ttl rename to ret-cli/src/test/resources/negative-objectproperty-assertion.ttl diff --git a/cli/src/test/resources/object-complement.ttl b/ret-cli/src/test/resources/object-complement.ttl similarity index 100% rename from cli/src/test/resources/object-complement.ttl rename to ret-cli/src/test/resources/object-complement.ttl diff --git a/cli/src/test/resources/object-intersection.ttl b/ret-cli/src/test/resources/object-intersection.ttl similarity index 100% rename from cli/src/test/resources/object-intersection.ttl rename to ret-cli/src/test/resources/object-intersection.ttl diff --git a/cli/src/test/resources/object-oneof.ttl b/ret-cli/src/test/resources/object-oneof.ttl similarity index 100% rename from cli/src/test/resources/object-oneof.ttl rename to ret-cli/src/test/resources/object-oneof.ttl diff --git a/cli/src/test/resources/object-union.ttl b/ret-cli/src/test/resources/object-union.ttl similarity index 100% rename from cli/src/test/resources/object-union.ttl rename to ret-cli/src/test/resources/object-union.ttl diff --git a/cli/src/test/resources/objectproperty-assertion.ttl b/ret-cli/src/test/resources/objectproperty-assertion.ttl similarity index 100% rename from cli/src/test/resources/objectproperty-assertion.ttl rename to ret-cli/src/test/resources/objectproperty-assertion.ttl diff --git a/cli/src/test/resources/objectproperty-domain.ttl b/ret-cli/src/test/resources/objectproperty-domain.ttl similarity index 100% rename from cli/src/test/resources/objectproperty-domain.ttl rename to ret-cli/src/test/resources/objectproperty-domain.ttl diff --git a/cli/src/test/resources/objectproperty-range.ttl b/ret-cli/src/test/resources/objectproperty-range.ttl similarity index 100% rename from cli/src/test/resources/objectproperty-range.ttl rename to ret-cli/src/test/resources/objectproperty-range.ttl diff --git a/cli/src/test/resources/property-chain.ttl b/ret-cli/src/test/resources/property-chain.ttl similarity index 100% rename from cli/src/test/resources/property-chain.ttl rename to ret-cli/src/test/resources/property-chain.ttl diff --git a/cli/src/test/resources/reflexive-objectproperty.ttl b/ret-cli/src/test/resources/reflexive-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/reflexive-objectproperty.ttl rename to ret-cli/src/test/resources/reflexive-objectproperty.ttl diff --git a/cli/src/test/resources/restriction-allvaluesfrom.ttl b/ret-cli/src/test/resources/restriction-allvaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-allvaluesfrom.ttl rename to ret-cli/src/test/resources/restriction-allvaluesfrom.ttl diff --git a/cli/src/test/resources/restriction-data-allvaluesfrom.ttl b/ret-cli/src/test/resources/restriction-data-allvaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-allvaluesfrom.ttl rename to ret-cli/src/test/resources/restriction-data-allvaluesfrom.ttl diff --git a/cli/src/test/resources/restriction-data-exact-cardinality.ttl b/ret-cli/src/test/resources/restriction-data-exact-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-exact-cardinality.ttl rename to ret-cli/src/test/resources/restriction-data-exact-cardinality.ttl diff --git a/cli/src/test/resources/restriction-data-hasvalue.ttl b/ret-cli/src/test/resources/restriction-data-hasvalue.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-hasvalue.ttl rename to ret-cli/src/test/resources/restriction-data-hasvalue.ttl diff --git a/cli/src/test/resources/restriction-data-max-cardinality.ttl b/ret-cli/src/test/resources/restriction-data-max-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-max-cardinality.ttl rename to ret-cli/src/test/resources/restriction-data-max-cardinality.ttl diff --git a/cli/src/test/resources/restriction-data-min-cardinality.ttl b/ret-cli/src/test/resources/restriction-data-min-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-min-cardinality.ttl rename to ret-cli/src/test/resources/restriction-data-min-cardinality.ttl diff --git a/cli/src/test/resources/restriction-data-somevaluesfrom.ttl b/ret-cli/src/test/resources/restriction-data-somevaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-data-somevaluesfrom.ttl rename to ret-cli/src/test/resources/restriction-data-somevaluesfrom.ttl diff --git a/cli/src/test/resources/restriction-has-self.ttl b/ret-cli/src/test/resources/restriction-has-self.ttl similarity index 100% rename from cli/src/test/resources/restriction-has-self.ttl rename to ret-cli/src/test/resources/restriction-has-self.ttl diff --git a/cli/src/test/resources/restriction-object-exact-cardinality.ttl b/ret-cli/src/test/resources/restriction-object-exact-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-exact-cardinality.ttl rename to ret-cli/src/test/resources/restriction-object-exact-cardinality.ttl diff --git a/cli/src/test/resources/restriction-object-hasvalue.ttl b/ret-cli/src/test/resources/restriction-object-hasvalue.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-hasvalue.ttl rename to ret-cli/src/test/resources/restriction-object-hasvalue.ttl diff --git a/cli/src/test/resources/restriction-object-max-cardinality.ttl b/ret-cli/src/test/resources/restriction-object-max-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-max-cardinality.ttl rename to ret-cli/src/test/resources/restriction-object-max-cardinality.ttl diff --git a/cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl b/ret-cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl rename to ret-cli/src/test/resources/restriction-object-qualified-min-cardinality.ttl diff --git a/cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl b/ret-cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl similarity index 100% rename from cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl rename to ret-cli/src/test/resources/restriction-object-unqualified-min-cardinality.ttl diff --git a/cli/src/test/resources/restriction-somevaluesfrom.ttl b/ret-cli/src/test/resources/restriction-somevaluesfrom.ttl similarity index 100% rename from cli/src/test/resources/restriction-somevaluesfrom.ttl rename to ret-cli/src/test/resources/restriction-somevaluesfrom.ttl diff --git a/cli/src/test/resources/same-individuals.ttl b/ret-cli/src/test/resources/same-individuals.ttl similarity index 100% rename from cli/src/test/resources/same-individuals.ttl rename to ret-cli/src/test/resources/same-individuals.ttl diff --git a/cli/src/test/resources/subannotationproperty.ttl b/ret-cli/src/test/resources/subannotationproperty.ttl similarity index 100% rename from cli/src/test/resources/subannotationproperty.ttl rename to ret-cli/src/test/resources/subannotationproperty.ttl diff --git a/cli/src/test/resources/subclass.ttl b/ret-cli/src/test/resources/subclass.ttl similarity index 100% rename from cli/src/test/resources/subclass.ttl rename to ret-cli/src/test/resources/subclass.ttl diff --git a/cli/src/test/resources/subdataproperty.ttl b/ret-cli/src/test/resources/subdataproperty.ttl similarity index 100% rename from cli/src/test/resources/subdataproperty.ttl rename to ret-cli/src/test/resources/subdataproperty.ttl diff --git a/cli/src/test/resources/subobjectproperty.ttl b/ret-cli/src/test/resources/subobjectproperty.ttl similarity index 100% rename from cli/src/test/resources/subobjectproperty.ttl rename to ret-cli/src/test/resources/subobjectproperty.ttl diff --git a/cli/src/test/resources/swrl-rule-builtin-atom.ttl b/ret-cli/src/test/resources/swrl-rule-builtin-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-builtin-atom.ttl rename to ret-cli/src/test/resources/swrl-rule-builtin-atom.ttl diff --git a/cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl b/ret-cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl rename to ret-cli/src/test/resources/swrl-rule-class-atom-with-expression.ttl diff --git a/cli/src/test/resources/swrl-rule-class-atom.ttl b/ret-cli/src/test/resources/swrl-rule-class-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-class-atom.ttl rename to ret-cli/src/test/resources/swrl-rule-class-atom.ttl diff --git a/cli/src/test/resources/swrl-rule-data-range-atom.ttl b/ret-cli/src/test/resources/swrl-rule-data-range-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-data-range-atom.ttl rename to ret-cli/src/test/resources/swrl-rule-data-range-atom.ttl diff --git a/cli/src/test/resources/swrl-rule-object-property-atom.ttl b/ret-cli/src/test/resources/swrl-rule-object-property-atom.ttl similarity index 100% rename from cli/src/test/resources/swrl-rule-object-property-atom.ttl rename to ret-cli/src/test/resources/swrl-rule-object-property-atom.ttl diff --git a/cli/src/test/resources/symmetric-objectproperty.ttl b/ret-cli/src/test/resources/symmetric-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/symmetric-objectproperty.ttl rename to ret-cli/src/test/resources/symmetric-objectproperty.ttl diff --git a/cli/src/test/resources/transitive-objectproperty.ttl b/ret-cli/src/test/resources/transitive-objectproperty.ttl similarity index 100% rename from cli/src/test/resources/transitive-objectproperty.ttl rename to ret-cli/src/test/resources/transitive-objectproperty.ttl From e8a32eb291f697eb31b4987d3e442aa584c04bbe Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 24 Nov 2023 11:16:49 +0100 Subject: [PATCH 148/280] Add core module --- .gitignore | 4 +- pom.xml | 6 + ret-core/pom.xml | 137 ++++++++++++++++++ .../buildtime/StringTemplate.java | 19 +++ .../buildtime/WriteVersionClass.java | 115 +++++++++++++++ 5 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 ret-core/pom.xml create mode 100644 ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java create mode 100644 ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java diff --git a/.gitignore b/.gitignore index 12c24471..5b98c7be 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ docs/modules/ROOT/assets/images/*.svg **/.flattened-pom.xml -*/target \ No newline at end of file +*/target + +**/src-gen \ No newline at end of file diff --git a/pom.xml b/pom.xml index f26443d8..e0f21a56 100644 --- a/pom.xml +++ b/pom.xml @@ -75,6 +75,7 @@ + ret-core ret-diagram-owl ret-infer ret-write @@ -95,6 +96,11 @@ + + de.atextor.ret + ret-core + ${project.version} + de.atextor.ret ret-diagram-owl diff --git a/ret-core/pom.xml b/ret-core/pom.xml new file mode 100644 index 00000000..681522ad --- /dev/null +++ b/ret-core/pom.xml @@ -0,0 +1,137 @@ + + + + ret + de.atextor.ret + 1.0-SNAPSHOT + + 4.0.0 + + ret-core + + + ${project.basedir}/src-gen/main/resources/git.properties + ${project.basedir}/src-gen + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-src-gen-source + initialize + + add-source + + + + ${generated-sources}/main/java + + + + + add-src-gen-resource + initialize + + add-resource + + + + + ${generated-sources}/main/resources + + + + + + add-src-buildtime-source + initialize + + add-source + + + + ${project.basedir}/src-buildtime/main/java + + + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + + ${generated-sources} + + + + + + + pl.project13.maven + git-commit-id-plugin + + + get-the-git-infos + generate-sources + + revision + + + + + ${project.basedir}/../.git + true + ${git-properties-filename} + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile-build-time-code + process-sources + + compile + + + ${project.basedir}/src-buildtime + + + + + + + org.codehaus.mojo + exec-maven-plugin + + + generate-version-class + generate-resources + + java + + + de.atextor.ret.core.buildtime.WriteVersionClass + + + + ${git-properties-filename} de.atextor.ret.core.Version ${generated-sources}/main/java/de/atextor/ret/core/Version.java + + + + + + + + \ No newline at end of file diff --git a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java new file mode 100644 index 00000000..8532131c --- /dev/null +++ b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java @@ -0,0 +1,19 @@ +package de.atextor.ret.core.buildtime; + +import java.util.Map; + +public class StringTemplate { + private final String template; + + public StringTemplate( final String template ) { + this.template = template; + } + + public String render( final Map values ) { + String result = template; + for ( final Map.Entry entry : values.entrySet() ) { + result = result.replace( "${" + entry.getKey() + "}", entry.getValue().toString() ); + } + return result; + } +} diff --git a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java new file mode 100644 index 00000000..c820da5b --- /dev/null +++ b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java @@ -0,0 +1,115 @@ +/* + * Copyright 2023 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.atextor.ret.core.buildtime; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.Properties; + +/** + * This class is executed at build time and will write Java file containing static build version information. + */ +public class WriteVersionClass { + private static final StringTemplate VERSION_CLASS_TEMPLATE = new StringTemplate( """ + /* + * Copyright ${year} ${copyrightHolder} + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package ${package}; + + /** + * Provides static build version information. + * Generated class, do not edit. + */ + public class ${className} { + public static final String VERSION = "${version}"; + public static final String BUILD_DATE = "${buildDate}"; + } + """ ); + + /** + * args[0]: the path to git.properties + * args[1]: fully qualified class name to generate + * args[2]: the path to the file to write + */ + public static void main( final String[] args ) { + final String gitPropertiesFile = args[0]; + final String fullyQualifiedClassName = args[1]; + final int lastDot = fullyQualifiedClassName.lastIndexOf( "." ); + final String packageName = fullyQualifiedClassName.substring( 0, lastDot ); + final String className = fullyQualifiedClassName.substring( lastDot + 1 ); + + final Properties gitProperties; + try ( final InputStream gitPropertiesInputStream = new FileInputStream( gitPropertiesFile ) ) { + gitProperties = new Properties(); + gitProperties.load( gitPropertiesInputStream ); + } catch ( final IOException exception ) { + System.err.println( "Could not open git.properties" ); + System.exit( 1 ); + return; + } + + final File targetFile = new File( args[2] ); + if ( !targetFile.getParentFile().mkdirs() ) { + System.err.println( "Could not create directory: " + targetFile.getParentFile() ); + System.exit( 1 ); + } + + final String gitBuildVersion = gitProperties.getProperty( "git.build.version" ); + final String version = gitBuildVersion.contains( "SNAPSHOT" ) + ? "%s (commit %s)".formatted( + gitBuildVersion, gitProperties.getProperty( "git.commit.id" ).substring( 0, 7 ) ) + : gitBuildVersion; + final String buildDate = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ); + final String content = VERSION_CLASS_TEMPLATE.render( Map.of( + "year", new SimpleDateFormat( "yyyy" ).format( new Date() ), + // For now. May read this from contributors file in the future. + "copyrightHolder", "Andreas Textor", + "package", packageName, + "className", className, + "version", version, + "buildDate", buildDate + ) ); + + try { + final BufferedWriter writer = new BufferedWriter( new FileWriter( targetFile ) ); + writer.write( content ); + writer.close(); + } catch ( final IOException exception ) { + throw new RuntimeException( exception ); + } + } +} From f403ff9acd3dbf77fcf820ab4f7ea47897db4079 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 24 Nov 2023 12:25:59 +0100 Subject: [PATCH 149/280] Adjust cli module build --- pom.xml | 5 ++ ret-cli/pom.xml | 62 +++++++++++++------ .../de/atextor/ret/cli/AbstractCommand.java | 22 +++---- .../main/java/de/atextor/ret/cli/OWLCLI.java | 3 +- .../java/de/atextor/ret/cli/OWLCLIConfig.java | 6 -- .../atextor/ret/cli/OWLCLIDiagramCommand.java | 3 +- .../atextor/ret/cli/OWLCLIInferCommand.java | 3 +- .../atextor/ret/cli/OWLCLIWriteCommand.java | 3 +- ret-cli/src/main/resources/logback.xml | 32 ++++++++++ .../ret/cli/BinaryIntegrationTest.java | 2 + .../de/atextor/ret/cli/CommandLineTest.java | 2 + .../de/atextor/ret/cli/MainClassRunner.java | 2 +- ret-core/pom.xml | 8 +++ 13 files changed, 113 insertions(+), 40 deletions(-) delete mode 100644 ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java create mode 100644 ret-cli/src/main/resources/logback.xml diff --git a/pom.xml b/pom.xml index e0f21a56..50234aa5 100644 --- a/pom.xml +++ b/pom.xml @@ -116,6 +116,11 @@ ret-write ${project.version} + + de.atextor.ret + ret-cli + ${project.version} + diff --git a/ret-cli/pom.xml b/ret-cli/pom.xml index 74ef57c7..f0efb138 100644 --- a/ret-cli/pom.xml +++ b/ret-cli/pom.xml @@ -19,6 +19,10 @@ + + de.atextor.ret + ret-core + de.atextor.ret ret-diagram-owl @@ -33,24 +37,16 @@ - - - - - - - - - - - - - - - - - - + + net.sourceforge.owlapi + owlapi-distribution + + + org.slf4j + slf4j-simple + + + com.github.ben-manes.caffeine caffeine @@ -143,6 +139,36 @@ true + + + org.apache.maven.plugins + maven-surefire-plugin + + + + **/CommandLineTest.java + **/DiagramCommandTest.java + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + **/*IntegrationTest.java + + + diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java index 17d62017..3d90d5de 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java @@ -118,17 +118,17 @@ protected OWLOntologyManager createOWLOntologyManager() { final Set storerFactories = ImmutableSet.builder() - .add( new org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory() ) - .add( new org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory() ) - .add( new org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory() ) - .add( new org.semanticweb.owlapi.latex.renderer.LatexStorerFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory() ) - .build(); + .add( new org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory() ) + .add( new org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory() ) + .add( new org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory() ) + .add( new org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory() ) + .add( new org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory() ) + .add( new org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory() ) + .add( new org.semanticweb.owlapi.latex.renderer.LatexStorerFactory() ) + .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory() ) + .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory() ) + .add( new org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory() ) + .build(); final OWLDataFactory dataFactory = new OWLDataFactoryImpl(); final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java index b2e14e6e..439eea3e 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java @@ -17,6 +17,7 @@ package de.atextor.ret.cli; import ch.qos.logback.classic.Level; +import de.atextor.ret.core.Version; import io.vavr.collection.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -95,7 +96,7 @@ public void run() { } if ( version ) { - System.out.printf( "owl-cli version: %s build date: %s%n", OWLCLIConfig.VERSION, OWLCLIConfig.BUILD_DATE ); + System.out.printf( "owl-cli version: %s build date: %s%n", Version.VERSION, Version.BUILD_DATE ); System.exit( 0 ); } diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java deleted file mode 100644 index f6bc010f..00000000 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -package de.atextor.ret.cli; - -public class OWLCLIConfig { - public static final String VERSION = ""; - public static final String BUILD_DATE = ""; -} diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java index 3b1582e3..bce78dcc 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java @@ -16,6 +16,7 @@ package de.atextor.ret.cli; +import de.atextor.ret.core.Version; import de.atextor.ret.diagram.owl.Configuration; import de.atextor.ret.diagram.owl.DiagramGenerator; import de.atextor.ret.diagram.owl.GraphvizDocument; @@ -31,7 +32,7 @@ parameterListHeading = "%n@|bold Parameters|@:%n", optionListHeading = "%n@|bold Options|@:%n", footer = "%nSee the online documentation for details:%n" + - "https://atextor.de/owl-cli/main/" + OWLCLIConfig.VERSION + "/usage.html#diagram-command" + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#diagram-command" ) public class OWLCLIDiagramCommand extends AbstractCommand implements Runnable { private static final Logger LOG = LoggerFactory.getLogger( OWLCLIDiagramCommand.class ); diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java index 0f841f00..67781cf1 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java @@ -16,6 +16,7 @@ package de.atextor.ret.cli; +import de.atextor.ret.core.Version; import de.atextor.ret.infer.Configuration; import de.atextor.ret.infer.Inferrer; import org.slf4j.Logger; @@ -31,7 +32,7 @@ parameterListHeading = "%n@|bold Parameters|@:%n", optionListHeading = "%n@|bold Options|@:%n", footer = "%nSee the online documentation for details:%n" + - "https://atextor.de/owl-cli/main/" + OWLCLIConfig.VERSION + "/usage.html#infer-command" + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#infer-command" ) public class OWLCLIInferCommand extends AbstractCommand implements Runnable { private static final Logger LOG = LoggerFactory.getLogger( OWLCLIInferCommand.class ); diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java index 76141f8d..3ef0f9df 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java @@ -16,6 +16,7 @@ package de.atextor.ret.cli; +import de.atextor.ret.core.Version; import de.atextor.ret.write.Configuration; import de.atextor.ret.write.RdfWriter; import de.atextor.turtle.formatter.FormattingStyle; @@ -45,7 +46,7 @@ parameterListHeading = "%n@|bold Parameters|@:%n", optionListHeading = "%n@|bold Options|@:%n", footer = "%nSee the online documentation for details:%n" + - "https://atextor.de/owl-cli/main/" + OWLCLIConfig.VERSION + "/usage.html#write-command" + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#write-command" ) public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { private static final Logger LOG = LoggerFactory.getLogger( OWLCLIWriteCommand.class ); diff --git a/ret-cli/src/main/resources/logback.xml b/ret-cli/src/main/resources/logback.xml new file mode 100644 index 00000000..a0cb59ae --- /dev/null +++ b/ret-cli/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + + System.out + + %m%n + + + + + + + + + + + diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java index fd5d77aa..a794e37b 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java @@ -21,6 +21,7 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; @@ -45,6 +46,7 @@ * binary with the corresponding command line switches. This is important, because this tests whether the binary * was built and starts correctly. */ +@Disabled public class BinaryIntegrationTest { private final Runtime runtime = Runtime.getRuntime(); diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java index 5f0c5344..3ede256f 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java @@ -16,11 +16,13 @@ package de.atextor.ret.cli; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static de.atextor.ret.cli.MainClassRunner.run; import static org.assertj.core.api.Assertions.assertThat; +@Disabled public class CommandLineTest { @Test public void testNoArguments() { diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java b/ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java index a2851827..f4a1f19c 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java @@ -20,7 +20,7 @@ import java.io.PrintStream; public class MainClassRunner { - record ExecutionResult(int exitStatus, String stdOut, String stdErr) { + record ExecutionResult( int exitStatus, String stdOut, String stdErr ) { } /** diff --git a/ret-core/pom.xml b/ret-core/pom.xml index 681522ad..fbb8ff9f 100644 --- a/ret-core/pom.xml +++ b/ret-core/pom.xml @@ -131,6 +131,14 @@ + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + From ba5458c98fc4f148fb5273c88be1db2a7a84d776 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 15:56:56 +0100 Subject: [PATCH 150/280] Fix ret-cli test and native-build setup --- pom.xml | 20 +- ret-cli/pom.xml | 225 ++++++++-- .../main/java/de/atextor/ret/cli/OWLCLI.java | 6 +- .../atextor/ret/cli/OWLCLIDiagramCommand.java | 6 +- .../atextor/ret/cli/OWLCLIWriteCommand.java | 6 +- .../de.atextor/owlcli/native-image.properties | 31 +- .../de.atextor/owlcli/reflect-config.json | 24 +- .../ret/cli/BinaryIntegrationTest.java | 399 ------------------ .../java/de/atextor/ret/cli/BinaryTest.java | 43 ++ .../cli/CaptureSystemExitSecurityManager.java | 45 -- .../java/de/atextor/ret/cli/CliRunner.java | 205 +++++++++ .../de/atextor/ret/cli/CommandLineTest.java | 57 --- .../atextor/ret/cli/DiagramCommandTest.java | 105 ----- .../de/atextor/ret/cli/ExecutableJarTest.java | 57 +++ .../de/atextor/ret/cli/MainClassRunner.java | 63 --- .../java/de/atextor/ret/cli/OwlCliTest.java | 270 ++++++++++++ .../ret/cli/SystemExitCapturedException.java | 21 - .../atextor/ret/cli/TestExecutionLogger.java | 44 ++ ret-core/pom.xml | 7 + .../java/de/atextor/ret/core/RdfLoader.java | 46 ++ 20 files changed, 932 insertions(+), 748 deletions(-) delete mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java create mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java delete mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/CaptureSystemExitSecurityManager.java create mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/CliRunner.java delete mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java delete mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/DiagramCommandTest.java create mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/ExecutableJarTest.java delete mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/MainClassRunner.java create mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/OwlCliTest.java delete mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/SystemExitCapturedException.java create mode 100644 ret-cli/src/test/java/de/atextor/ret/cli/TestExecutionLogger.java create mode 100644 ret-core/src/main/java/de/atextor/ret/core/RdfLoader.java diff --git a/pom.xml b/pom.xml index 50234aa5..ae638eca 100644 --- a/pom.xml +++ b/pom.xml @@ -66,11 +66,14 @@ 1.4.1 0.8.9 3.8.1 + 3.0.0 3.0.1 3.3.2 + 3.4.1 3.2.1 1.2.1 3.0.0-M7 + 0.9.28 1.6.8 @@ -283,6 +286,11 @@ maven-compiler-plugin ${maven-compiler-plugin-version} + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin-version} + org.apache.maven.plugins maven-gpg-plugin @@ -293,6 +301,11 @@ maven-javadoc-plugin ${maven-javadoc-plugin-version} + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin-version} + org.apache.maven.plugins maven-source-plugin @@ -303,6 +316,11 @@ maven-surefire-plugin ${maven-surefire-plugin-version} + + org.graalvm.buildtools + native-maven-plugin + ${native-maven-plugin-version} + org.sonatype.plugins nexus-staging-maven-plugin @@ -419,7 +437,7 @@ false - ${project.build.directory}/${testreports.surefire} + ${project.build.directory}/surefire-reports **/*Tests.java **/*Test.java diff --git a/ret-cli/pom.xml b/ret-cli/pom.xml index f0efb138..9f479547 100644 --- a/ret-cli/pom.xml +++ b/ret-cli/pom.xml @@ -15,6 +15,14 @@ 17 17 UTF-8 + + false + false + false + ${project.artifactId}-${project.version} + ${project.artifactId}-${project.version}-for-native + de.atextor.ret.cli.OWLCLI + owl @@ -37,16 +45,6 @@ - - net.sourceforge.owlapi - owlapi-distribution - - - org.slf4j - slf4j-simple - - - com.github.ben-manes.caffeine caffeine @@ -55,6 +53,10 @@ commons-codec commons-codec + + commons-io + commons-io + com.google.guava guava @@ -103,11 +105,6 @@ assertj-core test - - commons-io - commons-io - test - io.github.classgraph classgraph @@ -144,10 +141,11 @@ org.apache.maven.plugins maven-surefire-plugin - + 1 + false + ${skip.maven.surefire} - **/CommandLineTest.java - **/DiagramCommandTest.java + **/OwlCliTest.java @@ -157,19 +155,198 @@ maven-failsafe-plugin + integration-test integration-test - verify + + + ${project.build.directory}/${project.artifactId}-${project.version}.jar + + ${project.build.directory}/${binary-name} + + 1 + true + + **/ExecutableJarTest.java + **/BinaryTest.java + + - - - **/*IntegrationTest.java - - + + + org.apache.maven.plugins + maven-shade-plugin + + + shade-for-native-image + package + + shade + + + ${native-image-jar} + false + ${skip.maven.shade} + + + + ${main-class} + + + + + + + + org.graalvm.sdk:graal-sdk + org.graalvm.nativeimage:svm + org.graalvm.truffle:truffle-api + org.graalvm.nativeimage:native-image-base + org.graalvm.nativeimage:pointsto + org.graalvm.nativeimage:objectfile + org.graalvm.compiler:compiler + + + + + + *:* + + module-info.class + META-INF/* + META-INF/sisu/javax.inject.Named + META-INF/plexus/components.xml + META-INF.versions*/** + META-INF/versions*/** + META-INF/maven/** + plugin.xml + about.html + + + + + ${project.groupId}:${project.artifactId} + false + + ** + META-INF/** + git.properties + + + + de/atextor/ret/core/buildtime/** + + + + + + + default-shade + package + + shade + + + ${regular-jar} + false + ${skip.maven.shade} + + + + ${main-class} + + + + + + + + *:* + + module-info.class + META-INF/* + META-INF/sisu/javax.inject.Named + META-INF/plexus/components.xml + META-INF.versions*/** + META-INF/versions*/** + META-INF/maven/** + plugin.xml + about.html + + + + + ${project.groupId}:${project.artifactId} + false + + ** + META-INF/** + git.properties + + + + de/atextor/ret/core/buildtime/** + + + + + + + + + + + native + + true + true + + + + + + org.graalvm.buildtools + native-maven-plugin + ${native-maven-plugin-version} + true + + + build-native + + compile + + pre-integration-test + + + + ${main-class} + ${binary-name} + ${skip.native.build} + true + + -J-XX:MaxRAMPercentage=90.0 + -J-XX:GCTimeRatio=19 + -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED + -J--add-exports=java.desktop/sun.font=ALL-UNNAMED + + true + + ${project.build.directory}/${native-image-jar}.jar + + + + + + + \ No newline at end of file diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java index 439eea3e..a1d84f1e 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java @@ -26,7 +26,9 @@ import java.io.PrintWriter; import java.util.logging.LogManager; -@CommandLine.Command( name = "owl", +import static de.atextor.ret.cli.OWLCLI.COMMAND_NAME; + +@CommandLine.Command( name = COMMAND_NAME, description = "Command line tool for ontology engineering", subcommands = { CommandLine.HelpCommand.class }, headerHeading = "@|bold Usage|@:%n%n", @@ -36,6 +38,8 @@ footer = "%nSee the online documentation: https://atextor.de/owl-cli/" ) public class OWLCLI implements Runnable { + public static final String COMMAND_NAME = "owl"; + private static final Logger LOG = LoggerFactory.getLogger( OWLCLI.class ); private static void printError( final CommandLine commandLine, final Exception exception ) { diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java index bce78dcc..3488606d 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java @@ -26,7 +26,9 @@ import org.slf4j.LoggerFactory; import picocli.CommandLine; -@CommandLine.Command( name = "diagram", +import static de.atextor.ret.cli.OWLCLIDiagramCommand.COMMAND_NAME; + +@CommandLine.Command( name = COMMAND_NAME, description = "Generate automatically-layouted diagrams for an ontology", descriptionHeading = "%n@|bold Description|@:%n%n", parameterListHeading = "%n@|bold Parameters|@:%n", @@ -35,6 +37,8 @@ "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#diagram-command" ) public class OWLCLIDiagramCommand extends AbstractCommand implements Runnable { + public static final String COMMAND_NAME = "diagram"; + private static final Logger LOG = LoggerFactory.getLogger( OWLCLIDiagramCommand.class ); private static final Configuration config = GraphvizDocument.DEFAULT_CONFIGURATION; diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java index 3ef0f9df..c0271766 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java @@ -40,7 +40,9 @@ import java.util.function.BiFunction; import java.util.stream.Collectors; -@CommandLine.Command( name = "write", +import static de.atextor.ret.cli.OWLCLIWriteCommand.COMMAND_NAME; + +@CommandLine.Command( name = COMMAND_NAME, description = "Read a given RDF document and write it out, possibly in a different format", descriptionHeading = "%n@|bold Description|@:%n%n", parameterListHeading = "%n@|bold Parameters|@:%n", @@ -49,6 +51,8 @@ "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#write-command" ) public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { + public static final String COMMAND_NAME = "write"; + private static final Logger LOG = LoggerFactory.getLogger( OWLCLIWriteCommand.class ); private static final Configuration config = RdfWriter.DEFAULT_CONFIGURATION; diff --git a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties index 601cf551..b8656e27 100644 --- a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties +++ b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties @@ -1,5 +1,5 @@ # -# Copyright 2021 Andreas Textor +# Copyright 2024 Andreas Textor # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,25 +14,32 @@ # limitations under the License. # -ImageName = owl -Args = -H:ConfigurationFileDirectories=${.},${.}/../../picocli-generated/owl-cli/cli \ +Args = -H:Name=${binary-name} \ + --no-fallback \ + --report-unsupported-elements-at-runtime \ + -H:EnableURLProtocols=http,https \ + --enable-https \ + -H:-UseServiceLoaderFeature \ + -H:+AllowIncompleteClasspath \ + -H:+ReportExceptionStackTraces \ + -H:+PrintClassInitialization \ + -H:-DeadlockWatchdogExitOnTimeout \ + -H:DeadlockWatchdogInterval=0 \ + -H:ConfigurationFileDirectories=${.},${.}/../../picocli-generated/owl-cli/cli \ --initialize-at-build-time=uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl \ --initialize-at-build-time=org.slf4j.impl.SimpleLogger \ --initialize-at-build-time=org.slf4j.LoggerFactory \ --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder \ - --initialize-at-build-time=ch.qos.logback.core.util.Loader \ - --initialize-at-build-time=ch.qos.logback.core.util.StatusPrinter \ --initialize-at-build-time=ch.qos.logback.classic.Level \ --initialize-at-build-time=ch.qos.logback.classic.Logger \ + --initialize-at-build-time=ch.qos.logback.classic.PatternLayout \ + --initialize-at-build-time=ch.qos.logback.core.util.Loader \ + --initialize-at-build-time=ch.qos.logback.core.util.StatusPrinter \ --initialize-at-build-time=ch.qos.logback.core.status.InfoStatus \ --initialize-at-build-time=ch.qos.logback.core.status.StatusBase \ --initialize-at-build-time=ch.qos.logback.core.spi.AppenderAttachableImpl \ + --initialize-at-build-time=ch.qos.logback.core.pattern.parser.TokenStream$1 \ + --initialize-at-build-time=ch.qos.logback.core.pattern.parser.Parser \ --initialize-at-build-time=org.apache.jena.base.module.SubsystemRegistryServiceLoader \ --initialize-at-build-time=org.apache.jena.util.LocationMapper \ - --initialize-at-build-time=org.apache.jena.riot.system.stream.JenaIOEnvironment \ - -H:-UseServiceLoaderFeature \ - -H:+AllowIncompleteClasspath \ - -H:EnableURLProtocols=http,https \ - -H:+ReportExceptionStackTraces \ - --no-fallback \ - --report-unsupported-elements-at-runtime \ No newline at end of file + --initialize-at-build-time=org.apache.jena.riot.system.stream.JenaIOEnvironment diff --git a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json index 85d2bd91..9b90e818 100644 --- a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json +++ b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json @@ -270,30 +270,30 @@ "methods":[{"name":"","parameterTypes":[] }] }, { - "name":"de.atextor.owlcli.AbstractCommand", + "name":"de.atextor.ret.cli.AbstractCommand", "allDeclaredFields":true, "allDeclaredMethods":true }, { - "name":"de.atextor.owlcli.LoggingMixin", + "name":"de.atextor.ret.cli.LoggingMixin", "allDeclaredFields":true, "allDeclaredMethods":true, "methods":[{"name":"","parameterTypes":[] }] }, { - "name":"de.atextor.owlcli.OWLCLI", + "name":"de.atextor.ret.cli.OWLCLI", "allDeclaredFields":true, "allDeclaredMethods":true, "allPublicMethods":true }, { - "name":"de.atextor.owlcli.OWLCLIDiagramCommand", + "name":"de.atextor.ret.cli.OWLCLIDiagramCommand", "allDeclaredFields":true, "allDeclaredMethods":true, "allPublicMethods":true }, { - "name":"de.atextor.owlcli.OWLCLIWriteCommand", + "name":"de.atextor.ret.cli.OWLCLIWriteCommand", "allDeclaredFields":true, "allDeclaredMethods":true }, @@ -416,20 +416,12 @@ "name":"java.util.PropertyPermission" }, { - "name":"org.apache.jena.ext.com.google.common.cache.Striped64", + "name":"com.github.jsonldjava.shaded.com.google.common.cache.Striped64", "fields":[ {"name":"base", "allowUnsafeAccess":true}, {"name":"busy", "allowUnsafeAccess":true} ] }, -{ - "name":"org.apache.jena.rdfxml.xmlinput.JenaReader", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"org.apache.jena.ttl.turtle.TurtleReader", - "methods":[{"name":"","parameterTypes":[] }] -}, { "name":"org.apache.jena.rdf.model.impl.NTripleReader", "methods":[{"name":"","parameterTypes":[] }] @@ -449,10 +441,6 @@ {"name":"REENTRANT"} ] }, -{ - "name":"org.apache.jena.rdfxml.xmloutput.impl.Basic", - "methods":[{"name":"","parameterTypes":[] }] -}, { "name":"org.semanticweb.owlapi.dlsyntax.parser.DLSyntaxOWLParserFactory", "allPublicConstructors":true diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java deleted file mode 100644 index a794e37b..00000000 --- a/ret-cli/src/test/java/de/atextor/ret/cli/BinaryIntegrationTest.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.ret.cli; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ArgumentsSource; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -/** - * This test runs several subcommands and see if they work correctly. This is done by calling the built native - * binary with the corresponding command line switches. This is important, because this tests whether the binary - * was built and starts correctly. - */ -@Disabled -public class BinaryIntegrationTest { - private final Runtime runtime = Runtime.getRuntime(); - - static String owl; - - /** - * This is set by the gradle build. If you want to run the tests in the IDE, you need to add - * -DowlBinary=/path/to/owl to the VM arguments. - */ - @BeforeAll - public static void setup() { - owl = System.getProperty( "owlBinary" ); - } - - @Test - public void testWithoutArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).contains( "Usage: owl [-hv] [--version] [COMMAND]" ); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testHelp() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " --help" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).contains( "Usage: owl [-hv] [--version] [COMMAND]" ); - assertThat( stdout ).contains( "See the online documentation" ); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testInvalidArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " definitelynotavalidargument" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 1 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).contains( "Error: " ); - } - - @Test - public void testHelpDiagram() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " help diagram" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).contains( "Usage: owl diagram" ); - assertThat( stdout ).contains( "--direction=" ); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testDiagramWithoutArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " diagram" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 1 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).contains( "Error: " ); - } - - @Test - public void testDiagramWithInvalidArguments() throws IOException, InterruptedException { - final Process process = runtime.exec( owl + " diagram definitelynotavalidargument" ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - assertThat( process.exitValue() ).isEqualTo( 1 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).contains( "Error: " ); - } - - @ParameterizedTest - @ArgumentsSource( ResourceArgumentsProvider.class ) - public void testDiagramGeneration( final String testFileName ) throws IOException, InterruptedException { - final Path tempDir = Files.createTempDirectory( "owldiagram" ); - - final URL input = DiagramCommandTest.class.getResource( "/" + testFileName + ".ttl" ); - final File output = tempDir.resolve( testFileName + ".ttl" ).toFile(); - - assertThat( input ).isNotNull(); - FileUtils.copyURLToFile( input, output ); - assertThat( output ).isFile(); - assertThat( fileContent( output ) ).isNotEmpty(); - - final String command = owl + " diagram " + output.getAbsolutePath(); - final Process process = runtime.exec( command ); - final String stdout = IOUtils.toString( process.getInputStream(), StandardCharsets.UTF_8 ); - final String stderr = IOUtils.toString( process.getErrorStream(), StandardCharsets.UTF_8 ); - process.waitFor(); - - if ( process.exitValue() != 0 ) { - System.out.println( "Something went wrong for " + command ); - System.out.println( "=== stdout ===" ); - System.out.println( stdout ); - System.out.println( "=== stderr ===" ); - System.out.println( stderr ); - } - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( stdout ).isEmpty(); - assertThat( stderr ).isEmpty(); - - final File writtenFile = tempDir.resolve( testFileName + ".svg" ).toFile(); - assertThat( writtenFile ).isFile(); - assertThat( fileContent( writtenFile ) ).contains( " . - @prefix rdfs: . - - :Person a rdfs:Class . - :name a rdfs:Property . - :address a rdfs:Property . - :city a rdfs:Property . - :Max a :Person ; - :name "Max" ; - :address [ - :city "City Z" - ] . - """; - return new ByteArrayInputStream( turtleDocument.getBytes() ); - } - - private InputStream rdfXmlInputStream() { - final String rdfXmlDocument = """ - - - - - -
- Max - - - - City Z - - - - - - - - - - - - """; - return new ByteArrayInputStream( rdfXmlDocument.getBytes() ); - } - - private InputStream ntripleInputStream() { - final String ntripleDocument = """ - . - . - . - _:gen0 "City Z"^^ . - _:gen0 . - "Max"^^ . - . - . - """; - return new ByteArrayInputStream( ntripleDocument.getBytes() ); - } - - private Model parseModel( final String document, final String format ) { - final Model model = ModelFactory.createDefaultModel(); - try { - model.read( new StringReader( document ), "", format ); - return model; - } catch ( final Throwable t ) { - return null; - } - } - - private boolean canBeParsedAs( final String document, final String format, final int expectedNumberOfStatements ) { - final Model model = parseModel( document, format ); - return model != null && model.listStatements().toList().size() == expectedNumberOfStatements; - } - - - @Test - public void testWriteTurtle() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( turtleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "TURTLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testWriteRdfXml() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -o rdfxml -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( turtleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "RDF/XML", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testWriteNtriple() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -o ntriple -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( turtleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "N-TRIPLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testReadRdfXml() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -i rdfxml -o turtle -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( rdfXmlInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "TURTLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testReadNtriple() throws InterruptedException, IOException { - final Process process = runtime.exec( owl + " write -i ntriple -o turtle -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.copy( ntripleInputStream(), process.getOutputStream() ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( process.exitValue() ).isEqualTo( 0 ); - assertThat( canBeParsedAs( stdout, "TURTLE", 8 ) ).isTrue(); - assertThat( stderr ).isEmpty(); - } - - @Test - public void testWriteTurtleWithEmptyBase() throws InterruptedException, IOException { - final String turtleDocument = """ - @prefix rdfs: . - @prefix : . - - :Person a rdfs:Class ; - :foo <> . - """; - - final Process process = runtime.exec( owl + " write -" ); - final BufferedReader stdoutReader = new BufferedReader( new InputStreamReader( process.getInputStream() ) ); - final BufferedReader stderrReader = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ); - IOUtils.write( turtleDocument, process.getOutputStream(), StandardCharsets.UTF_8 ); - process.getOutputStream().close(); - process.waitFor(); - - final String stdout = IOUtils.toString( stdoutReader ); - final String stderr = IOUtils.toString( stderrReader ); - - assertThat( stdout ).isEqualToIgnoringWhitespace( turtleDocument ); - } -} diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java new file mode 100644 index 00000000..1f1b1b3f --- /dev/null +++ b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.atextor.ret.cli; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.io.File; + +import static org.assertj.core.api.Assumptions.assumeThat; + +@ExtendWith( TestExecutionLogger.class ) +public class BinaryTest extends OwlCliTest { + private static File binary; + + @BeforeAll + static void beforeMethod() { + final String binaryPath = System.getProperty( "binary" ); + assumeThat( binaryPath ).isNotNull(); + binary = new File( binaryPath ); + assumeThat( binary ).isFile(); + assumeThat( binary ).exists(); + } + + @Override + protected CliRunner.Result runCli( final CliRunner.ExecArguments arguments ) { + return CliRunner.runBinary( binary, arguments ); + } +} diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/CaptureSystemExitSecurityManager.java b/ret-cli/src/test/java/de/atextor/ret/cli/CaptureSystemExitSecurityManager.java deleted file mode 100644 index 10db2538..00000000 --- a/ret-cli/src/test/java/de/atextor/ret/cli/CaptureSystemExitSecurityManager.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.ret.cli; - -import java.security.Permission; - -public class CaptureSystemExitSecurityManager extends SecurityManager { - private final SecurityManager delegateSecurityManager; - private int exitCode = 0; - - CaptureSystemExitSecurityManager( final SecurityManager delegateSecurityManager ) { - this.delegateSecurityManager = delegateSecurityManager; - } - - int getExitCode() { - return exitCode; - } - - @Override - public void checkPermission( final Permission permission ) { - if ( delegateSecurityManager != null ) { - delegateSecurityManager.checkPermission( permission ); - } - } - - @Override - public void checkExit( final int i ) { - exitCode = i; - throw new SystemExitCapturedException(); - } -} diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/CliRunner.java b/ret-cli/src/test/java/de/atextor/ret/cli/CliRunner.java new file mode 100644 index 00000000..0d42d5dd --- /dev/null +++ b/ret-cli/src/test/java/de/atextor/ret/cli/CliRunner.java @@ -0,0 +1,205 @@ +/* + * Copyright 2023 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.atextor.ret.cli; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.Serial; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.security.Permission; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * This method uses {@link System#getSecurityManager()} and {@link System#setSecurityManager(SecurityManager)} that + * are deprecated as of Java 17. However, until + * JDK-8199704 is addressed, + * we have still to rely on it. + */ +@SuppressWarnings( "removal" ) +public class CliRunner { + private static final Logger LOG = LoggerFactory.getLogger( CliRunner.class ); + + record StreamContent( byte[] raw ) { + public String asString() { + return new String( raw, StandardCharsets.UTF_8 ); + } + } + + record ExecArguments( List arguments, StreamContent stdin, File workingDirectory ) { + public ExecArguments( final List arguments, final StreamContent stdin ) { + this( arguments, stdin, new File( "." ).getAbsoluteFile() ); + } + + public ExecArguments( final List arguments ) { + this( arguments, new StreamContent( new byte[0] ) ); + } + + public ExecArguments( final String... arguments ) { + this( List.of( arguments ) ); + } + } + + record Result( int exitStatus, StreamContent stdOut, StreamContent stdErr ) { + } + + private static class CaptureSystemExitSecurityManager extends SecurityManager { + private final SecurityManager delegateSecurityManager; + + private int exitCode = 0; + + CaptureSystemExitSecurityManager( final SecurityManager delegateSecurityManager ) { + this.delegateSecurityManager = delegateSecurityManager; + } + + int getExitCode() { + return exitCode; + } + + @Override + public void checkPermission( final Permission permission ) { + if ( delegateSecurityManager != null ) { + delegateSecurityManager.checkPermission( permission ); + } + } + + @Override + public void checkExit( final int i ) { + exitCode = i; + throw new SystemExitCapturedException(); + } + } + + private static class SystemExitCapturedException extends RuntimeException { + @Serial + private static final long serialVersionUID = 6080552325336609875L; + } + + private record StreamCollector( InputStream in ) implements Callable { + @Override + public ByteArrayOutputStream call() throws Exception { + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + in.transferTo( buffer ); + return buffer; + } + } + + public static Result runMainClass( final Class clazz, final ExecArguments execArguments ) { + final SecurityManager originalSecurityManager = System.getSecurityManager(); + final CaptureSystemExitSecurityManager securityManager = new CaptureSystemExitSecurityManager( originalSecurityManager ); + System.setSecurityManager( securityManager ); + + final PrintStream originalStdout = System.out; + final PrintStream originalStderr = System.err; + final InputStream originalStdin = System.in; + final String originalUserDir = System.getProperty( "user.dir" ); + + try ( + final ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); + final ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream(); + final PrintStream outStream = new PrintStream( stdoutBuffer ); + final PrintStream errStream = new PrintStream( stderrBuffer ) + ) { + System.setOut( outStream ); + System.setErr( errStream ); + + if ( execArguments.stdin().raw().length > 0 ) { + System.setIn( new ByteArrayInputStream( execArguments.stdin().raw() ) ); + } + + System.setProperty( "user.dir", execArguments.workingDirectory().getAbsolutePath() ); + final Method method = clazz.getMethod( "main", String[].class ); + try { + method.invoke( null, (Object) execArguments.arguments().toArray( new String[0] ) ); + } catch ( final InvocationTargetException exception ) { + // Ignore System.exit, throw everything else + if ( !exception.getCause().getClass().equals( SystemExitCapturedException.class ) ) { + throw new RuntimeException( exception ); + } + } + return new Result( securityManager.getExitCode(), + new StreamContent( stdoutBuffer.toByteArray() ), + new StreamContent( stderrBuffer.toByteArray() ) ); + } catch ( final NoSuchMethodException | IllegalAccessException | IOException exception ) { + throw new RuntimeException( exception ); + } finally { + System.setSecurityManager( originalSecurityManager ); + System.setOut( originalStdout ); + System.setErr( originalStderr ); + if ( execArguments.stdin().raw().length > 0 ) { + System.setIn( originalStdin ); + } + System.setProperty( "user.dir", originalUserDir ); + } + } + + + public static Result runJar( final File jarFile, final ExecArguments execArguments, final List jvmArguments ) { + final File javaBinary = new File( ProcessHandle.current().info().command().orElse( "java" ) ); + + final List javaExecArguments = Stream.of( + jvmArguments.stream(), + Stream.of( "-jar", jarFile.toString() ), + execArguments.arguments().stream() + ).flatMap( Function.identity() ).toList(); + + return runBinary( javaBinary, new ExecArguments( javaExecArguments, execArguments.stdin(), execArguments.workingDirectory() ) ); + } + + public static Result runBinary( final File binary, final ExecArguments executionArgument ) { + LOG.debug( "Executing command (in {}): \"{}\" {}", + executionArgument.workingDirectory(), binary, executionArgument.arguments().stream() + .map( argument -> '"' + argument + '"' ) + .collect( Collectors.joining( " " ) ) ); + try { + final List commandWithAllArguments = + Stream.concat( Stream.of( binary.toString() ), executionArgument.arguments().stream() ).toList(); + final Process process = Runtime.getRuntime() + .exec( commandWithAllArguments.toArray( new String[0] ), null, executionArgument.workingDirectory() ); + if ( executionArgument.stdin().raw().length > 0 ) { + process.getOutputStream().write( executionArgument.stdin().raw() ); + } + process.getOutputStream().close(); + final ExecutorService executor = Executors.newFixedThreadPool( 2 ); + final Future stdout = executor.submit( new StreamCollector( process.getInputStream() ) ); + final Future stderr = executor.submit( new StreamCollector( process.getErrorStream() ) ); + process.waitFor(); + + return new Result( process.exitValue(), new StreamContent( stdout.get().toByteArray() ), + new StreamContent( stderr.get().toByteArray() ) ); + } catch ( final IOException | InterruptedException | ExecutionException exception ) { + throw new RuntimeException( exception ); + } + } +} + diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java deleted file mode 100644 index 3ede256f..00000000 --- a/ret-cli/src/test/java/de/atextor/ret/cli/CommandLineTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.ret.cli; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import static de.atextor.ret.cli.MainClassRunner.run; -import static org.assertj.core.api.Assertions.assertThat; - -@Disabled -public class CommandLineTest { - @Test - public void testNoArguments() { - final Runnable command = () -> OWLCLI.main( new String[]{} ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 0 ); - assertThat( result.stdOut() ).contains( "Usage: " ); - assertThat( result.stdErr() ).isEmpty(); - } - - @Test - public void testHelp() { - final Runnable command = () -> OWLCLI.main( new String[]{ "--help" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 0 ); - assertThat( result.stdOut() ).contains( "Usage: " ); - assertThat( result.stdErr() ).isEmpty(); - } - - @Test - public void testInvalidArguments() { - @SuppressWarnings( "SpellCheckingInspection" ) final Runnable command = () -> OWLCLI.main( new String[]{ - "definitelynotavalidargument" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 1 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).contains( "Error: " ); - } -} diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/DiagramCommandTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/DiagramCommandTest.java deleted file mode 100644 index 6d8895f4..00000000 --- a/ret-cli/src/test/java/de/atextor/ret/cli/DiagramCommandTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.ret.cli; - -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ArgumentsSource; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; - -import static de.atextor.ret.cli.MainClassRunner.run; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -public class DiagramCommandTest { - - private byte[] fileContent( final File file ) { - try { - return FileUtils.readFileToByteArray( file ); - } catch ( final IOException exception ) { - fail( "", exception ); - } - return null; - } - - @Test - public void testWithoutParameters() { - final Runnable command = () -> OWLCLI.main( new String[]{ "diagram" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 1 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).contains( "Error: " ); - } - - @Test - public void testWithInvalidInput() { - final Runnable command = () -> OWLCLI.main( new String[]{ "diagram", "definitelynotexistingfile" } ); - final MainClassRunner.ExecutionResult result = run( command ); - - assertThat( result.exitStatus() ).isEqualTo( 1 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).contains( "Error: " ); - } - - @ParameterizedTest - @ArgumentsSource( ResourceArgumentsProvider.class ) - public void testDiagramGeneration( final String testFileName ) throws IOException { - final Path tempDir = Files.createTempDirectory( "owldiagram" ); - - final URL input = DiagramCommandTest.class.getResource( "/" + testFileName + ".ttl" ); - final File output = tempDir.resolve( testFileName + ".ttl" ).toFile(); - - assertThat( input ).isNotNull(); - FileUtils.copyURLToFile( input, output ); - assertThat( output ).isFile(); - assertThat( fileContent( output ) ).isNotEmpty(); - - final Runnable command = () -> OWLCLI.main( new String[]{ "diagram", output.getAbsolutePath() } ); - final MainClassRunner.ExecutionResult result = run( command ); - - System.out.println( result.stdOut() ); - System.out.println( result.stdErr() ); - - if ( result.exitStatus() != 0 ) { - System.out.println( "Something went wrong for diagram " + output.getAbsolutePath() ); - System.out.println( "=== stdout ===" ); - System.out.println( result.stdOut() ); - System.out.println( "=== stderr ===" ); - System.out.println( result.stdErr() ); - } - assertThat( result.exitStatus() ).isEqualTo( 0 ); - assertThat( result.stdOut() ).isEmpty(); - assertThat( result.stdErr() ).isEmpty(); - - final File writtenFile = tempDir.resolve( testFileName + ".svg" ).toFile(); - assertThat( writtenFile ).isFile(); - assertThat( fileContent( writtenFile ) ).contains( "JDK-8199704 is addressed, - * we have still to rely on it. - * - * @param runnable the runnable to execute - * @return the {@link ExecutionResult} of the runnable - */ - public static ExecutionResult run( final Runnable runnable ) { - final SecurityManager originalSecurityManager = System.getSecurityManager(); - - final CaptureSystemExitSecurityManager securityManager = - new CaptureSystemExitSecurityManager( originalSecurityManager ); - System.setSecurityManager( securityManager ); - - final PrintStream originalStdOut = System.out; - final PrintStream originalStdErr = System.err; - final ByteArrayOutputStream stdOutBuffer = new ByteArrayOutputStream(); - final ByteArrayOutputStream stdErrBuffer = new ByteArrayOutputStream(); - final PrintStream newStdOut = new PrintStream( stdOutBuffer ); - final PrintStream newStdErr = new PrintStream( stdErrBuffer ); - System.setOut( newStdOut ); - System.setErr( newStdErr ); - - try { - runnable.run(); - } catch ( final SystemExitCapturedException e ) { - // Ignore - } finally { - System.setSecurityManager( originalSecurityManager ); - System.setOut( originalStdOut ); - System.setErr( originalStdErr ); - } - - return new ExecutionResult( securityManager.getExitCode(), stdOutBuffer.toString(), stdErrBuffer.toString() ); - } -} diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/OwlCliTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/OwlCliTest.java new file mode 100644 index 00000000..4ee06756 --- /dev/null +++ b/ret-cli/src/test/java/de/atextor/ret/cli/OwlCliTest.java @@ -0,0 +1,270 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.atextor.ret.cli; + +import org.apache.commons.io.FileUtils; +import org.apache.jena.riot.Lang; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static de.atextor.ret.core.RdfLoader.load; +import static de.atextor.ret.core.RdfLoader.loadTurtle; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +@ExtendWith( TestExecutionLogger.class ) +public class OwlCliTest { + protected CliRunner.Result runCli( final CliRunner.ExecArguments arguments ) { + return CliRunner.runMainClass( OWLCLI.class, arguments ); + } + + private static Path tempDir; + + // Process return codes + private final int OK = 0; + + private final int ERROR = 1; + + @BeforeEach + void beforeEach() throws IOException { + tempDir = Files.createTempDirectory( "junit" ); + } + + @AfterEach + void afterEach() throws IOException { +// FileUtils.deleteDirectory( tempDir.toFile() ); + } + + @AfterAll + static void afterAll() throws IOException { + if ( tempDir != null && tempDir.toFile().exists() ) { +// FileUtils.deleteDirectory( tempDir.toFile() ); + } + } + + @Test + void testNoArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( List.of() ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().asString() ).as( "stdout" ).contains( "Usage:" ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + } + + @Test + void testHelp() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "--help" ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().asString() ).as( "stdout" ).contains( "Usage:" ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + } + + @Test + void testInvalidArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "invalid_argument" ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().asString() ).as( "stderr" ).contains( "Error:" ); + } + + @Test + void testHelpDiagram() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "help", OWLCLIDiagramCommand.COMMAND_NAME ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().asString() ).as( "stdout" ) + .contains( "Usage: " + OWLCLI.COMMAND_NAME + " " + OWLCLIDiagramCommand.COMMAND_NAME ); + assertThat( result.stdOut().asString() ).as( "stdout" ).contains( "--direction=" ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + } + + @Test + void testDiagramWithoutArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( OWLCLIDiagramCommand.COMMAND_NAME ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().asString() ).as( "stderr" ).contains( "Error:" ); + assertThat( result.stdErr().asString() ).as( "stderr" ) + .contains( "Usage: " + OWLCLI.COMMAND_NAME + " " + OWLCLIDiagramCommand.COMMAND_NAME ); + } + + @Test + void testDiagramWithInvalidArguments() { + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( OWLCLIDiagramCommand.COMMAND_NAME, "invalid_argument" ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().asString() ).as( "stderr" ).contains( "Error:" ); + } + + @ParameterizedTest + @ArgumentsSource( ResourceArgumentsProvider.class ) + void testDiagramGeneration( final String testFileName ) throws IOException { + final URL input = OwlCliTest.class.getResource( "/" + testFileName + ".ttl" ); + final File output = tempDir.resolve( testFileName + ".ttl" ).toFile(); + + assertThat( input ).isNotNull(); + FileUtils.copyURLToFile( input, output ); + assertThat( output ).isFile(); + assertThat( output ).content().isNotEmpty(); + + final List arguments = List.of( OWLCLIDiagramCommand.COMMAND_NAME, output.getAbsolutePath() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + final File writtenFile = tempDir.resolve( testFileName + ".svg" ).toFile(); + assertThat( writtenFile ).isFile(); + assertThat( writtenFile ).content().contains( " . + @prefix rdfs: . + + :Person a rdfs:Class . + :name a rdfs:Property . + :address a rdfs:Property . + :city a rdfs:Property . + :Max a :Person ; + :name "Max" ; + :address [ + :city "City Z" + ] . + """; + final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( turtleDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> loadTurtle( result.stdOut().asString() ) ).doesNotThrowAnyException(); + } + + @Test + void testWriteRdfXml() { + final String rdfXmlDocument = """ + + + + + +
+ Max + + + + City Z + + + + + + + + + + + + """; + final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-i", "rdfxml", "-o", "rdfxml", "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( rdfXmlDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> load( result.stdOut().asString(), Lang.RDFXML ) ).doesNotThrowAnyException(); + } + + @Test + void testWriteNTriple() { + final String ntripleDocument = """ + . + . + . + _:gen0 "City Z"^^ . + _:gen0 . + "Max"^^ . + . + . + """; + final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-i", "ntriple", "-o", "ntriple", "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( ntripleDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> load( result.stdOut().asString(), Lang.NTRIPLES ) ).doesNotThrowAnyException(); + } + + @Test + void testWriteTurtleWithEmptyBase() { + final String turtleDocument = """ + @prefix rdfs: . + @prefix : . + + :Person a rdfs:Class ; + :foo <> . + """; + final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-" ); + final CliRunner.StreamContent stdin = new CliRunner.StreamContent( turtleDocument.getBytes() ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); + assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); + assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); + assertThatCode( () -> loadTurtle( result.stdOut().asString() ) ).doesNotThrowAnyException(); + assertThat( result.stdOut().asString() ).isEqualToIgnoringWhitespace( turtleDocument ); + } +} diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/SystemExitCapturedException.java b/ret-cli/src/test/java/de/atextor/ret/cli/SystemExitCapturedException.java deleted file mode 100644 index 9d9ff912..00000000 --- a/ret-cli/src/test/java/de/atextor/ret/cli/SystemExitCapturedException.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.ret.cli; - -public class SystemExitCapturedException extends RuntimeException { - private static final long serialVersionUID = 6080552325336609875L; -} diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/TestExecutionLogger.java b/ret-cli/src/test/java/de/atextor/ret/cli/TestExecutionLogger.java new file mode 100644 index 00000000..28d593b2 --- /dev/null +++ b/ret-cli/src/test/java/de/atextor/ret/cli/TestExecutionLogger.java @@ -0,0 +1,44 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.atextor.ret.cli; + +import org.junit.jupiter.api.extension.AfterTestExecutionCallback; +import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Optional; + +public class TestExecutionLogger implements BeforeTestExecutionCallback, AfterTestExecutionCallback { + private static final Logger LOG = LoggerFactory.getLogger( TestExecutionLogger.class ); + + @Override + public void beforeTestExecution( final ExtensionContext context ) throws Exception { + LOG.info( "Run test " + context.getDisplayName() ); + } + + @Override + public void afterTestExecution( final ExtensionContext context ) { + final Optional executionException = context.getExecutionException(); + if ( executionException.isPresent() ) { + LOG.info( "Exception in test {}:", context.getDisplayName(), executionException.get() ); + } else { + LOG.info( " {}: success", context.getDisplayName() ); + } + } +} diff --git a/ret-core/pom.xml b/ret-core/pom.xml index fbb8ff9f..c9bc985e 100644 --- a/ret-core/pom.xml +++ b/ret-core/pom.xml @@ -16,6 +16,13 @@ ${project.basedir}/src-gen + + + org.apache.jena + jena-arq + + + diff --git a/ret-core/src/main/java/de/atextor/ret/core/RdfLoader.java b/ret-core/src/main/java/de/atextor/ret/core/RdfLoader.java new file mode 100644 index 00000000..67840adf --- /dev/null +++ b/ret-core/src/main/java/de/atextor/ret/core/RdfLoader.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.atextor.ret.core; + +import org.apache.jena.rdf.model.Model; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFParser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +public class RdfLoader { + public static Model load( final String document, final Lang syntax ) { + final InputStream input = new ByteArrayInputStream( document.getBytes( StandardCharsets.UTF_8 ) ); + final Model result = RDFParser.create() + .source( input ) + .lang( syntax ) + .toModel(); + try { + input.close(); + } catch ( final IOException e ) { + // Ignore + } + return result; + } + + public static Model loadTurtle( final String document ) { + return load( document, Lang.TURTLE ); + } +} From e816219313d81c6813cd4c9306da463ca405ee0f Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 15:58:48 +0100 Subject: [PATCH 151/280] Clean up Maven setup --- pom.xml | 35 ++++++++++++++++++++++++++++++++++- ret-core/pom.xml | 5 +++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ae638eca..a8621e51 100644 --- a/pom.xml +++ b/pom.xml @@ -8,9 +8,18 @@ 1.0-SNAPSHOT pom - RDF Engineering Toolkit + RDF Engineering Toolkit + The RDF Engineering Toolkit (ret) provides APIs and a command line interface to transform, manipulate, + validate and visualize RDF and OWL documents. + + 2019 https://github.com/atextor/ret + + Github + https://github.com/atextor/ret/issues + + Apache License, Version 2.0 @@ -63,8 +72,12 @@ 1.8.0 + 3.3.0 + 3.1.0 1.4.1 + 4.9.10 0.8.9 + 3.2.0 3.8.1 3.0.0 3.0.1 @@ -271,16 +284,36 @@ + + org.codehaus.mojo + build-helper-maven-plugin + ${build-helper-maven-plugin-version} + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin-version} + org.codehaus.mojo flatten-maven-plugin ${flatten-maven-plugin-version} + + pl.project13.maven + git-commit-id-plugin + ${git-commit-id-plugin-version} + org.jacoco jacoco-maven-plugin ${jacoco-maven-plugin-version} + + org.apache.maven.plugins + maven-clean-plugin + ${maven-clean-plugin-version} + org.apache.maven.plugins maven-compiler-plugin diff --git a/ret-core/pom.xml b/ret-core/pom.xml index c9bc985e..1d5559ff 100644 --- a/ret-core/pom.xml +++ b/ret-core/pom.xml @@ -14,6 +14,7 @@ ${project.basedir}/src-gen/main/resources/git.properties ${project.basedir}/src-gen + ${project.basedir}/src-buildtime @@ -63,7 +64,7 @@ - ${project.basedir}/src-buildtime/main/java + ${build-time-sources}/main/java @@ -112,7 +113,7 @@ compile - ${project.basedir}/src-buildtime + ${build-time-sources} From a72d329444115bba32b48ecbb4fc339658929527 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 15:59:07 +0100 Subject: [PATCH 152/280] Clean up code style --- .../main/java/de/atextor/ret/cli/LoggingMixin.java | 12 ++++-------- .../java/de/atextor/ret/cli/OWLCLIInferCommand.java | 5 ++++- .../atextor/ret/cli/ResourceArgumentsProvider.java | 13 ++++++++----- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java index acce383d..99b1822c 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java @@ -56,14 +56,10 @@ public boolean[] getVerbosity() { public Level calcLogLevel() { return switch ( getVerbosity().length ) { - case 0: - yield Level.WARN; - case 1: - yield Level.INFO; - case 2: - yield Level.DEBUG; - default: - yield Level.TRACE; + case 0 -> Level.WARN; + case 1 -> Level.INFO; + case 2 -> Level.DEBUG; + default -> Level.TRACE; }; } diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java index 67781cf1..c00c53db 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java @@ -26,7 +26,9 @@ import java.net.MalformedURLException; import java.net.URL; -@CommandLine.Command( name = "infer", +import static de.atextor.ret.cli.OWLCLIInferCommand.COMMAND_NAME; + +@CommandLine.Command( name = COMMAND_NAME, description = "Runs an OWL reasoner on an ontology", descriptionHeading = "%n@|bold Description|@:%n%n", parameterListHeading = "%n@|bold Parameters|@:%n", @@ -35,6 +37,7 @@ "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#infer-command" ) public class OWLCLIInferCommand extends AbstractCommand implements Runnable { + public static final String COMMAND_NAME = "infer"; private static final Logger LOG = LoggerFactory.getLogger( OWLCLIInferCommand.class ); private static final Configuration config = Inferrer.DEFAULT_CONFIGURATION; diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/ResourceArgumentsProvider.java b/ret-cli/src/test/java/de/atextor/ret/cli/ResourceArgumentsProvider.java index 0bdb4cc5..ff0f876f 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/ResourceArgumentsProvider.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/ResourceArgumentsProvider.java @@ -17,6 +17,7 @@ package de.atextor.ret.cli; import io.github.classgraph.ClassGraph; +import io.github.classgraph.ScanResult; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; @@ -29,11 +30,13 @@ public class ResourceArgumentsProvider implements ArgumentsProvider { @Override public Stream provideArguments( final ExtensionContext context ) { - return new ClassGraph().scan().getResourcesWithExtension( ".ttl" ).getPaths().stream() - .map( filename -> filename.replace( ".ttl", "" ) ) - .filter( filename -> !filename.contains( "/" ) ) - .sorted() - .map( FilenameArguments::new ); + try ( final ScanResult scanResult = new ClassGraph().scan() ) { + return scanResult.getResourcesWithExtension( ".ttl" ).getPaths().stream() + .map( filename -> filename.replace( ".ttl", "" ) ) + .filter( filename -> !filename.contains( "/" ) ) + .sorted() + .map( FilenameArguments::new ); + } } public static class FilenameArguments implements Arguments { From ae9adb41b75df0f30ea23ebffa35d18a1635bc9c Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 15:59:31 +0100 Subject: [PATCH 153/280] Remove Gradle build files --- build.gradle | 97 --------- dependencies.gradle | 49 ----- gradle.properties | 17 -- gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 - gradlew | 245 ----------------------- gradlew.bat | 92 --------- settings.gradle | 22 -- 8 files changed, 528 deletions(-) delete mode 100644 build.gradle delete mode 100644 dependencies.gradle delete mode 100644 gradle.properties delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradlew delete mode 100644 gradlew.bat delete mode 100644 settings.gradle diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 69807f27..00000000 --- a/build.gradle +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id 'java' - id 'jacoco' - id 'com.github.ben-manes.versions' version '0.48.0' - id 'com.adarshr.test-logger' version '3.2.0' apply false - id 'io.freefair.lombok' version '8.3' apply false - id 'com.github.johnrengelman.shadow' version '8.1.1' apply false - id 'org.ajoberstar.grgit' version '5.2.0' -} - -allprojects { - repositories { - mavenCentral() - } -} - -def currentTag = { - def grgit = grgit.open{ dir = "${projectDir}" } - def tag = grgit.describe{ tags = true } - if (tag != null) { - tag.startsWith('snapshot') ? 'snapshot' : tag.replace('v', '') - } else { - 'snapshot' - } -} - -subprojects { - version = currentTag() - task allDeps(type: DependencyReportTask) {} - ext { - homeDir = System.getProperty("user.home") - lombokAnnotationProcessor = 'lombok.launch.AnnotationProcessorHider$AnnotationProcessor' - lombokClaimingProcessor = 'lombok.launch.AnnotationProcessorHider$ClaimingProcessor' - picocliProcessor = 'picocli.codegen.aot.graalvm.processor.NativeImageConfigGeneratorProcessor' - } -} - -apply plugin: 'jacoco' -apply plugin: 'java' - -task jacocoRootReport(type: JacocoReport, group: 'Coverage reports') { - description = 'Generates an aggregate report from all subprojects' - classDirectories.from = [ - "${projectDir}/cli/build/classes/java/main", - "${projectDir}/diagram/build/classes/java/main", - "${projectDir}/write/build/classes/java/main", - "${projectDir}/infer/build/classes/java/main", - ] - sourceDirectories.from = [ - "${projectDir}/cli/src/main/java", - "${projectDir}/diagram/src/main/java", - "${projectDir}/write/src/main/java", - "${projectDir}/infer/src/main/java", - ] - - executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec") - reports { - html.required = true - xml.required = true - xml.destination(file("${buildDir}/reports/jacoco/report.xml")) - csv.required = false - } - - dependsOn ':test' - dependsOn ':cli:test' - dependsOn ':diagram:test' - dependsOn ':write:test' - dependsOn ':infer:test' -} - -defaultTasks 'test', 'shadowJar' - -def isNonStable = { String version -> - return ['ALPHA', 'BETA', 'RC', 'M'].any { it -> version.toUpperCase().contains(it) } -} - -dependencyUpdates { - rejectVersionIf { - isNonStable(it.candidate.version) - } -} diff --git a/dependencies.gradle b/dependencies.gradle deleted file mode 100644 index ec3ad6cc..00000000 --- a/dependencies.gradle +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -ext.deps = [ - caffeine: 'com.github.ben-manes.caffeine:caffeine:2.9.2', - commons_codec: 'commons-codec:commons-codec:1.16.0', - commons_io: 'org.apache.commons:commons-io:1.3.2', - commons_text: 'org.apache.commons:commons-text:1.10.0', - guava: 'com.google.guava:guava:32.1.2-jre', - httpclient: 'org.apache.httpcomponents:httpclient:4.5.14', - jackson_databind: 'com.fasterxml.jackson.core:jackson-databind:2.15.2', - jena: 'org.apache.jena:jena:4.9.0', - jena_core: 'org.apache.jena:jena-core:4.9.0', - jena_arq: 'org.apache.jena:jena-arq:4.9.0', - logback: 'ch.qos.logback:logback-classic:1.4.11', - openllet: 'com.github.galigator.openllet:openllet-jena:2.6.5', - owlapi: 'net.sourceforge.owlapi:owlapi-distribution:5.5.0', - picocli: 'info.picocli:picocli:4.7.5', - picocli_codegen: 'info.picocli:picocli-codegen:4.7.5', - slf4j_api: 'org.slf4j:slf4j-api:2.0.9', - svm: 'org.graalvm.nativeimage:svm:23.1.0', - turtle_formatter: 'de.atextor:turtle-formatter:1.2.9', - vavr: 'io.vavr:vavr:0.10.4', - - // Test - junit_jupiter_api: 'org.junit.jupiter:junit-jupiter-api:5.10.0', - junit_jupiter_params: 'org.junit.jupiter:junit-jupiter-params:5.10.0', - junit_jupiter_engine: 'org.junit.jupiter:junit-jupiter-engine:5.10.0', - assertj: 'org.assertj:assertj-core:3.24.2', - jqwik: 'net.jqwik:jqwik:1.8.0', - classgraph: 'io.github.classgraph:classgraph:4.8.162', - - // Documentation - nodejs: '12.13.1', - npm: '6.9.0' -] diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 7d521816..00000000 --- a/gradle.properties +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright 2021 Andreas Textor -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -version=snapshot \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index c1962a79e29d3e0ab67b14947c167a862655af9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62076 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index bdc9a83b..00000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip -networkTimeout=10000 -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew deleted file mode 100755 index aeb74cbb..00000000 --- a/gradlew +++ /dev/null @@ -1,245 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 6689b85b..00000000 --- a/gradlew.bat +++ /dev/null @@ -1,92 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index b278086a..00000000 --- a/settings.gradle +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2021 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -rootProject.name = 'owl-cli' -include ':diagram' -include ':write' -include ':infer' -include ':cli' -include ':docs' From 377d989c664edb5fa045709dd6520ddf06ac0b59 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 16:24:37 +0100 Subject: [PATCH 154/280] Rename classes from OWL CLI to Ret --- ret-cli/pom.xml | 6 +- .../java/de/atextor/ret/cli/LoggingMixin.java | 2 +- .../atextor/ret/cli/{OWLCLI.java => Ret.java} | 18 +++--- ...CLIDiagramCommand.java => RetDiagram.java} | 31 +++++----- ...{OWLCLIInferCommand.java => RetInfer.java} | 10 ++- ...{OWLCLIWriteCommand.java => RetWrite.java} | 62 ++++++++++--------- .../de.atextor/owlcli/reflect-config.json | 11 +++- .../java/de/atextor/ret/cli/BinaryTest.java | 2 +- .../de/atextor/ret/cli/ExecutableJarTest.java | 2 +- .../ret/cli/{OwlCliTest.java => RetTest.java} | 36 +++++------ 10 files changed, 98 insertions(+), 82 deletions(-) rename ret-cli/src/main/java/de/atextor/ret/cli/{OWLCLI.java => Ret.java} (88%) rename ret-cli/src/main/java/de/atextor/ret/cli/{OWLCLIDiagramCommand.java => RetDiagram.java} (85%) rename ret-cli/src/main/java/de/atextor/ret/cli/{OWLCLIInferCommand.java => RetInfer.java} (91%) rename ret-cli/src/main/java/de/atextor/ret/cli/{OWLCLIWriteCommand.java => RetWrite.java} (90%) rename ret-cli/src/test/java/de/atextor/ret/cli/{OwlCliTest.java => RetTest.java} (88%) diff --git a/ret-cli/pom.xml b/ret-cli/pom.xml index 9f479547..a4941ef0 100644 --- a/ret-cli/pom.xml +++ b/ret-cli/pom.xml @@ -21,8 +21,8 @@ false ${project.artifactId}-${project.version} ${project.artifactId}-${project.version}-for-native - de.atextor.ret.cli.OWLCLI - owl + de.atextor.ret.cli.Ret + ret @@ -145,7 +145,7 @@ false ${skip.maven.surefire} - **/OwlCliTest.java + **/RetTest.java diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java index 99b1822c..116c42e3 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java @@ -35,7 +35,7 @@ public class LoggingMixin { private boolean[] verbosity = new boolean[0]; private static LoggingMixin getTopLevelCommandLoggingMixin( final CommandLine.Model.CommandSpec commandSpec ) { - return ( (OWLCLI) commandSpec.root().userObject() ).loggingMixin; + return ( (Ret) commandSpec.root().userObject() ).loggingMixin; } public static int executionStrategy( final CommandLine.ParseResult parseResult ) { diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java b/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java similarity index 88% rename from ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java rename to ret-cli/src/main/java/de/atextor/ret/cli/Ret.java index a1d84f1e..58a7acbb 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLI.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java @@ -26,7 +26,7 @@ import java.io.PrintWriter; import java.util.logging.LogManager; -import static de.atextor.ret.cli.OWLCLI.COMMAND_NAME; +import static de.atextor.ret.cli.Ret.COMMAND_NAME; @CommandLine.Command( name = COMMAND_NAME, description = "Command line tool for ontology engineering", @@ -37,10 +37,10 @@ optionListHeading = "%n@|bold Options|@:%n", footer = "%nSee the online documentation: https://atextor.de/owl-cli/" ) -public class OWLCLI implements Runnable { - public static final String COMMAND_NAME = "owl"; +public class Ret implements Runnable { + public static final String COMMAND_NAME = "ret"; - private static final Logger LOG = LoggerFactory.getLogger( OWLCLI.class ); + private static final Logger LOG = LoggerFactory.getLogger( Ret.class ); private static void printError( final CommandLine commandLine, final Exception exception ) { final Level logLevel = ( (LoggingMixin) commandLine.getMixins().values().iterator().next() ).calcLogLevel(); @@ -71,20 +71,22 @@ private static void printError( final CommandLine commandLine, final Exception e @CommandLine.Mixin LoggingMixin loggingMixin; + @SuppressWarnings( "unused" ) @CommandLine.Option( names = { "-h", "--help" }, usageHelp = true, description = "Show short help" ) private boolean helpRequested; + @SuppressWarnings( "unused" ) @CommandLine.Option( names = { "--version" }, description = "Show current version" ) private boolean version; public static void main( final String[] args ) { LogManager.getLogManager().reset(); final List commands = List.of( - new OWLCLIDiagramCommand(), - new OWLCLIWriteCommand(), - new OWLCLIInferCommand() + new RetDiagram(), + new RetWrite(), + new RetInfer() ); - final CommandLine cmd = commands.foldLeft( new OWLCLI().commandLine, CommandLine::addSubcommand ) + final CommandLine cmd = commands.foldLeft( new Ret().commandLine, CommandLine::addSubcommand ) .setParameterExceptionHandler( PARAMETER_EXCEPTION_HANDLER ) .setExecutionExceptionHandler( EXECUTION_EXCEPTION_HANDLER ) .setCaseInsensitiveEnumValuesAllowed( true ) diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java similarity index 85% rename from ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java rename to ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java index 3488606d..61ca30fa 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIDiagramCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; import picocli.CommandLine; -import static de.atextor.ret.cli.OWLCLIDiagramCommand.COMMAND_NAME; +import static de.atextor.ret.cli.RetDiagram.COMMAND_NAME; @CommandLine.Command( name = COMMAND_NAME, description = "Generate automatically-layouted diagrams for an ontology", @@ -36,69 +36,72 @@ footer = "%nSee the online documentation for details:%n" + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#diagram-command" ) -public class OWLCLIDiagramCommand extends AbstractCommand implements Runnable { +public class RetDiagram extends AbstractCommand implements Runnable { public static final String COMMAND_NAME = "diagram"; - private static final Logger LOG = LoggerFactory.getLogger( OWLCLIDiagramCommand.class ); + private static final Logger LOG = LoggerFactory.getLogger( RetDiagram.class ); private static final Configuration config = GraphvizDocument.DEFAULT_CONFIGURATION; @CommandLine.Mixin LoggingMixin loggingMixin; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--fontname" }, description = "The font to use (Default: ${DEFAULT-VALUE})" ) private String fontname = config.fontname; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--fontsize" }, description = "Default font size (Default: ${DEFAULT-VALUE})" ) private int fontsize = config.fontsize; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--nodefontname" }, description = "Font for nodes (Default: ${DEFAULT-VALUE})" ) private String nodeFontName = config.nodeFontname; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--nodefontsize" }, description = "Font size for nodes (Default: ${DEFAULT-VALUE})" ) private int nodeFontsize = config.nodeFontsize; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--nodeshape" }, description = "Node shape (Default: ${DEFAULT-VALUE})" ) private String nodeShape = config.nodeShape; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--nodemargin" }, description = "Node margin (Default: ${DEFAULT-VALUE})" ) private String nodeMargin = config.nodeMargin; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--nodestyle" }, description = "Node style (Default: ${DEFAULT-VALUE})" ) private String nodeStyle = config.nodeStyle; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--format" }, description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format format = config.format; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--direction" }, description = "Diagram layout direction, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.LayoutDirection layoutDirection = config.layoutDirection; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal" } ) @CommandLine.Option( names = { "--dotbinary" }, description = "Path to dot binary (Default: ${DEFAULT-VALUE})" ) private String dotBinary = config.dotBinary; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal" } ) @CommandLine.Option( names = { "--fgcolor" }, description = "Foreground color (Default: ${DEFAULT-VALUE})" ) private String fgColor = config.fgColor; + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal" } ) @CommandLine.Option( names = { "--bgcolor" }, description = "Background color (Default: ${DEFAULT-VALUE})" ) private String bgColor = config.bgColor; + @SuppressWarnings( "unused" ) @CommandLine.Parameters( paramLabel = "INPUT", description = "File name or - for stdin", arity = "1", index = "0" ) private String input; + @SuppressWarnings( "unused" ) @CommandLine.Parameters( paramLabel = "OUTPUT", description = "File name or - for stdout. If left out, the input file name is used, e.g. foo.ttl -> " + "foo.svg or stdout if INPUT is -.", diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java similarity index 91% rename from ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java rename to ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java index c00c53db..7a35eca3 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIInferCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java @@ -26,7 +26,7 @@ import java.net.MalformedURLException; import java.net.URL; -import static de.atextor.ret.cli.OWLCLIInferCommand.COMMAND_NAME; +import static de.atextor.ret.cli.RetInfer.COMMAND_NAME; @CommandLine.Command( name = COMMAND_NAME, description = "Runs an OWL reasoner on an ontology", @@ -36,19 +36,23 @@ footer = "%nSee the online documentation for details:%n" + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#infer-command" ) -public class OWLCLIInferCommand extends AbstractCommand implements Runnable { +public class RetInfer extends AbstractCommand implements Runnable { public static final String COMMAND_NAME = "infer"; - private static final Logger LOG = LoggerFactory.getLogger( OWLCLIInferCommand.class ); + private static final Logger LOG = LoggerFactory.getLogger( RetInfer.class ); + + @SuppressWarnings( "unused" ) private static final Configuration config = Inferrer.DEFAULT_CONFIGURATION; @CommandLine.Mixin LoggingMixin loggingMixin; + @SuppressWarnings( "unused" ) @CommandLine.Parameters( paramLabel = "INPUT", description = "File name, URL, or - for stdin", arity = "1", index = "0" ) private String input; + @SuppressWarnings( "unused" ) @CommandLine.Parameters( paramLabel = "OUTPUT", description = "File name or - for stdout. If left out, output is written to stdout.", arity = "0..1", index = "1" ) diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java similarity index 90% rename from ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java rename to ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java index c0271766..6dedba30 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/OWLCLIWriteCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java @@ -40,7 +40,7 @@ import java.util.function.BiFunction; import java.util.stream.Collectors; -import static de.atextor.ret.cli.OWLCLIWriteCommand.COMMAND_NAME; +import static de.atextor.ret.cli.RetWrite.COMMAND_NAME; @CommandLine.Command( name = COMMAND_NAME, description = "Read a given RDF document and write it out, possibly in a different format", @@ -50,10 +50,10 @@ footer = "%nSee the online documentation for details:%n" + "https://atextor.de/owl-cli/main/" + Version.VERSION + "/usage.html#write-command" ) -public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { +public class RetWrite extends AbstractCommand implements Runnable { public static final String COMMAND_NAME = "write"; - private static final Logger LOG = LoggerFactory.getLogger( OWLCLIWriteCommand.class ); + private static final Logger LOG = LoggerFactory.getLogger( RetWrite.class ); private static final Configuration config = RdfWriter.DEFAULT_CONFIGURATION; @@ -62,17 +62,17 @@ public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { @CommandLine.Mixin LoggingMixin loggingMixin; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "-o", "--output" }, description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format outputFormat = config.outputFormat; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "-i", "--input" }, description = "Input file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format inputFormat = config.inputFormat; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "-p", "--prefix" }, description = "Prefix to add as @prefix when used.", mapFallbackValue = fallbackUri ) @@ -83,116 +83,119 @@ public class OWLCLIWriteCommand extends AbstractCommand implements Runnable { description = "Alignment of @prefix statements, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Alignment alignPrefixes = FormattingStyle.DEFAULT.alignPrefixes; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--encoding" }, description = "Output encoding, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Charset encoding = FormattingStyle.DEFAULT.charset; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--doubleFormat" }, description = "Defines how double numbers are formatted (Default: ${DEFAULT-VALUE})" ) private String doubleFormatPattern = ( (DecimalFormat) FormattingStyle.DEFAULT.doubleFormat ).toPattern(); - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--endOfLine" }, description = "End of line style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.EndOfLineStyle endOfLineStyle = FormattingStyle.DEFAULT.endOfLine; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--indent" }, description = "Indent style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.IndentStyle indentStyle = FormattingStyle.DEFAULT.indentStyle; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--firstPredicateInNewLine" }, description = "Write first predicate in new line of block (Default: ${DEFAULT-VALUE})" ) private boolean firstPredicateInNewLine = FormattingStyle.DEFAULT.firstPredicateInNewLine; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--writeRdfType" }, description = "Write 'rdf:type' instead of 'a' (Default: ${DEFAULT-VALUE})" ) private boolean writeRdfType = !FormattingStyle.DEFAULT.useAForRdfType; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--useCommaByDefault" }, description = "Use commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private boolean useCommaByDefault = FormattingStyle.DEFAULT.useCommaByDefault; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--commaForPredicate" }, description = "A set of predicates that, when used multiple times, are separated by commas, even when " + "useCommaByDefault is false (Default: ${DEFAULT-VALUE})" ) private Set commaForPredicate = FormattingStyle.DEFAULT.commaForPredicate; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--noCommaForPredicate" }, description = "Use no commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private Set noCommaForPredicate = FormattingStyle.DEFAULT.noCommaForPredicate; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--useLongLiterals" }, description = "Use long form for literals where possible (Default: ${DEFAULT-VALUE})" ) private boolean useLongLiterals = !FormattingStyle.DEFAULT.useShortLiterals; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--alignObjects" }, description = "Align objects for same predicates (Default: ${DEFAULT-VALUE})" ) private boolean alignObjects = FormattingStyle.DEFAULT.alignObjects; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--alignPredicates" }, description = "Align predicates for same subjects (Default: ${DEFAULT-VALUE})" ) private boolean alignPredicates = FormattingStyle.DEFAULT.alignPredicates; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--continuationIndentSize" }, description = "Indentation size after forced line wraps (Default: ${DEFAULT-VALUE})" ) private int continuationIndentSize = FormattingStyle.DEFAULT.continuationIndentSize; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--doNotInsertFinalNewline" }, description = "Do not insert newline at end of file (Default: ${DEFAULT-VALUE})" ) private boolean doNotInsertFinalNewline = !FormattingStyle.DEFAULT.insertFinalNewline; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--indentSize" }, description = "Indentation size in spaces (Default: ${DEFAULT-VALUE})" ) private int indentSize = FormattingStyle.DEFAULT.indentSize; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--keepUnusedPrefixes" }, description = "Keeps prefixes that are not part of any statement (Default: ${DEFAULT-VALUE})" ) private boolean keepUnusedPrefixes = FormattingStyle.DEFAULT.keepUnusedPrefixes; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--prefixOrder" }, description = "Sort order for prefixes (Default: ${DEFAULT-VALUE})" ) private List prefixOrder = FormattingStyle.DEFAULT.prefixOrder; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--subjectOrder" }, description = "Sort order for subjects by type (Default: ${DEFAULT-VALUE})" ) private List subjectOrder = FormattingStyle.DEFAULT.subjectOrder; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--predicateOrder" }, description = "Sort order for predicates (Default: ${DEFAULT-VALUE})" ) private List predicateOrder = FormattingStyle.DEFAULT.predicateOrder; + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--objectOrder" }, description = "Sort order for objects (Default: ${DEFAULT-VALUE})" ) private List objectOrder = FormattingStyle.DEFAULT.objectOrder; - @SuppressWarnings( "CanBeFinal" ) + @SuppressWarnings( "FieldMayBeFinal" ) @CommandLine.Option( names = { "--anonymousNodeIdPattern" }, description = "Name pattern for blank node IDs (Default: ${DEFAULT-VALUE})" ) private String anonymousNodeIdPattern = FormattingStyle.DEFAULT.anonymousNodeIdGenerator.apply( ResourceFactory.createResource(), 0 ); + @SuppressWarnings( "unused" ) @CommandLine.Parameters( paramLabel = "INPUT", description = "File name, URL, or - for stdin", arity = "1", index = "0" ) private String input; + @SuppressWarnings( "unused" ) @CommandLine.Parameters( paramLabel = "OUTPUT", description = "File name or - for stdout. If left out, output is written to stdout.", arity = "0..1", index = "1" ) @@ -311,7 +314,7 @@ protected String buildResourceUri( final String resourceUri ) { private class PropertyConverter extends AbstractResourceConverter implements CommandLine.ITypeConverter { @Override - public Property convert( final String value ) throws Exception { + public Property convert( final String value ) { final String propertyUri = buildResourceUri( value ); return ResourceFactory.createProperty( propertyUri ); } @@ -319,7 +322,7 @@ public Property convert( final String value ) throws Exception { private class ResourceConverter extends AbstractResourceConverter implements CommandLine.ITypeConverter { @Override - public Resource convert( final String value ) throws Exception { + public Resource convert( final String value ) { final String propertyUri = buildResourceUri( value ); return ResourceFactory.createResource( propertyUri ); } @@ -327,10 +330,9 @@ public Resource convert( final String value ) throws Exception { private class RDFNodeConverter extends AbstractResourceConverter implements CommandLine.ITypeConverter { @Override - public RDFNode convert( final String value ) throws Exception { + public RDFNode convert( final String value ) { final String propertyUri = buildResourceUri( value ); return ResourceFactory.createResource( propertyUri ); } } - } diff --git a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json index 9b90e818..ae04cb9e 100644 --- a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json +++ b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/reflect-config.json @@ -281,22 +281,27 @@ "methods":[{"name":"","parameterTypes":[] }] }, { - "name":"de.atextor.ret.cli.OWLCLI", + "name":"de.atextor.ret.cli.Ret", "allDeclaredFields":true, "allDeclaredMethods":true, "allPublicMethods":true }, { - "name":"de.atextor.ret.cli.OWLCLIDiagramCommand", + "name":"de.atextor.ret.cli.RetDiagram", "allDeclaredFields":true, "allDeclaredMethods":true, "allPublicMethods":true }, { - "name":"de.atextor.ret.cli.OWLCLIWriteCommand", + "name":"de.atextor.ret.cli.RetWrite", "allDeclaredFields":true, "allDeclaredMethods":true }, + { + "name":"de.atextor.ret.cli.RetInfer", + "allDeclaredFields":true, + "allDeclaredMethods":true + }, { "name":"java.io.FilePermission" }, diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java index 1f1b1b3f..97556d16 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/BinaryTest.java @@ -24,7 +24,7 @@ import static org.assertj.core.api.Assumptions.assumeThat; @ExtendWith( TestExecutionLogger.class ) -public class BinaryTest extends OwlCliTest { +public class BinaryTest extends RetTest { private static File binary; @BeforeAll diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/ExecutableJarTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/ExecutableJarTest.java index 5bcf5397..34a33c2f 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/ExecutableJarTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/ExecutableJarTest.java @@ -28,7 +28,7 @@ import static org.assertj.core.api.Assumptions.assumeThat; @ExtendWith( TestExecutionLogger.class ) -public class ExecutableJarTest extends OwlCliTest { +public class ExecutableJarTest extends RetTest { private static File executableJar; @BeforeAll diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/OwlCliTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java similarity index 88% rename from ret-cli/src/test/java/de/atextor/ret/cli/OwlCliTest.java rename to ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java index 4ee06756..54af7f7b 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/OwlCliTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java @@ -39,9 +39,9 @@ import static org.assertj.core.api.Assertions.assertThatCode; @ExtendWith( TestExecutionLogger.class ) -public class OwlCliTest { +public class RetTest { protected CliRunner.Result runCli( final CliRunner.ExecArguments arguments ) { - return CliRunner.runMainClass( OWLCLI.class, arguments ); + return CliRunner.runMainClass( Ret.class, arguments ); } private static Path tempDir; @@ -94,27 +94,27 @@ void testInvalidArguments() { @Test void testHelpDiagram() { - final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "help", OWLCLIDiagramCommand.COMMAND_NAME ) ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "help", RetDiagram.COMMAND_NAME ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); assertThat( result.stdOut().asString() ).as( "stdout" ) - .contains( "Usage: " + OWLCLI.COMMAND_NAME + " " + OWLCLIDiagramCommand.COMMAND_NAME ); + .contains( "Usage: " + Ret.COMMAND_NAME + " " + RetDiagram.COMMAND_NAME ); assertThat( result.stdOut().asString() ).as( "stdout" ).contains( "--direction=" ); assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); } @Test void testDiagramWithoutArguments() { - final CliRunner.Result result = runCli( new CliRunner.ExecArguments( OWLCLIDiagramCommand.COMMAND_NAME ) ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( RetDiagram.COMMAND_NAME ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); assertThat( result.stdErr().asString() ).as( "stderr" ).contains( "Error:" ); assertThat( result.stdErr().asString() ).as( "stderr" ) - .contains( "Usage: " + OWLCLI.COMMAND_NAME + " " + OWLCLIDiagramCommand.COMMAND_NAME ); + .contains( "Usage: " + Ret.COMMAND_NAME + " " + RetDiagram.COMMAND_NAME ); } @Test void testDiagramWithInvalidArguments() { - final CliRunner.Result result = runCli( new CliRunner.ExecArguments( OWLCLIDiagramCommand.COMMAND_NAME, "invalid_argument" ) ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( RetDiagram.COMMAND_NAME, "invalid_argument" ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); assertThat( result.stdErr().asString() ).as( "stderr" ).contains( "Error:" ); @@ -123,7 +123,7 @@ void testDiagramWithInvalidArguments() { @ParameterizedTest @ArgumentsSource( ResourceArgumentsProvider.class ) void testDiagramGeneration( final String testFileName ) throws IOException { - final URL input = OwlCliTest.class.getResource( "/" + testFileName + ".ttl" ); + final URL input = RetTest.class.getResource( "/" + testFileName + ".ttl" ); final File output = tempDir.resolve( testFileName + ".ttl" ).toFile(); assertThat( input ).isNotNull(); @@ -131,7 +131,7 @@ void testDiagramGeneration( final String testFileName ) throws IOException { assertThat( output ).isFile(); assertThat( output ).content().isNotEmpty(); - final List arguments = List.of( OWLCLIDiagramCommand.COMMAND_NAME, output.getAbsolutePath() ); + final List arguments = List.of( RetDiagram.COMMAND_NAME, output.getAbsolutePath() ); final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); @@ -143,27 +143,27 @@ void testDiagramGeneration( final String testFileName ) throws IOException { @Test void testHelpWrite() { - final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "help", OWLCLIWriteCommand.COMMAND_NAME ) ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( "help", RetWrite.COMMAND_NAME ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); assertThat( result.stdOut().asString() ).as( "stdout" ) - .contains( "Usage: " + OWLCLI.COMMAND_NAME + " " + OWLCLIWriteCommand.COMMAND_NAME ); + .contains( "Usage: " + Ret.COMMAND_NAME + " " + RetWrite.COMMAND_NAME ); assertThat( result.stdOut().asString() ).as( "stdout" ).contains( "--alignObjects" ); assertThat( result.stdErr().raw() ).as( "stderr" ).isEmpty(); } @Test void testWriteWithoutArguments() { - final CliRunner.Result result = runCli( new CliRunner.ExecArguments( OWLCLIWriteCommand.COMMAND_NAME ) ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( RetWrite.COMMAND_NAME ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); assertThat( result.stdErr().asString() ).as( "stderr" ).contains( "Error:" ); assertThat( result.stdErr().asString() ).as( "stderr" ) - .contains( "Usage: " + OWLCLI.COMMAND_NAME + " " + OWLCLIWriteCommand.COMMAND_NAME ); + .contains( "Usage: " + Ret.COMMAND_NAME + " " + RetWrite.COMMAND_NAME ); } @Test void testWriteWithInvalidArguments() { - final CliRunner.Result result = runCli( new CliRunner.ExecArguments( OWLCLIWriteCommand.COMMAND_NAME, "invalid_argument" ) ); + final CliRunner.Result result = runCli( new CliRunner.ExecArguments( RetWrite.COMMAND_NAME, "invalid_argument" ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( ERROR ); assertThat( result.stdOut().raw() ).as( "stdout" ).isEmpty(); assertThat( result.stdErr().asString() ).as( "stderr" ).contains( "Error:" ); @@ -185,7 +185,7 @@ void testWriteTurtle() { :city "City Z" ] . """; - final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-" ); + final List arguments = List.of( RetWrite.COMMAND_NAME, "-" ); final CliRunner.StreamContent stdin = new CliRunner.StreamContent( turtleDocument.getBytes() ); final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); @@ -222,7 +222,7 @@ void testWriteRdfXml() { """; - final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-i", "rdfxml", "-o", "rdfxml", "-" ); + final List arguments = List.of( RetWrite.COMMAND_NAME, "-i", "rdfxml", "-o", "rdfxml", "-" ); final CliRunner.StreamContent stdin = new CliRunner.StreamContent( rdfXmlDocument.getBytes() ); final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); @@ -242,7 +242,7 @@ void testWriteNTriple() { . . """; - final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-i", "ntriple", "-o", "ntriple", "-" ); + final List arguments = List.of( RetWrite.COMMAND_NAME, "-i", "ntriple", "-o", "ntriple", "-" ); final CliRunner.StreamContent stdin = new CliRunner.StreamContent( ntripleDocument.getBytes() ); final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); @@ -259,7 +259,7 @@ void testWriteTurtleWithEmptyBase() { :Person a rdfs:Class ; :foo <> . """; - final List arguments = List.of( OWLCLIWriteCommand.COMMAND_NAME, "-" ); + final List arguments = List.of( RetWrite.COMMAND_NAME, "-" ); final CliRunner.StreamContent stdin = new CliRunner.StreamContent( turtleDocument.getBytes() ); final CliRunner.Result result = runCli( new CliRunner.ExecArguments( arguments, stdin ) ); assertThat( result.exitStatus() ).as( "command return code" ).isEqualTo( OK ); From 3f57c5d0aeef6e8318705c5cfedc98cff0d371fd Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 16:24:50 +0100 Subject: [PATCH 155/280] Fix Maven shade warnings --- ret-cli/pom.xml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ret-cli/pom.xml b/ret-cli/pom.xml index a4941ef0..6ecfe976 100644 --- a/ret-cli/pom.xml +++ b/ret-cli/pom.xml @@ -210,6 +210,17 @@ org.graalvm.nativeimage:pointsto org.graalvm.nativeimage:objectfile org.graalvm.compiler:compiler + + + + net.sourceforge.owlapi:owlapi-api + net.sourceforge.owlapi:owlapi-apibinding + net.sourceforge.owlapi:owlapi-compatibility + net.sourceforge.owlapi:owlapi-impl + net.sourceforge.owlapi:owlapi-parsers + net.sourceforge.owlapi:owlapi-oboformat + net.sourceforge.owlapi:owlapi-rio + net.sourceforge.owlapi:owlapi-tools @@ -265,6 +276,20 @@ + + + + + net.sourceforge.owlapi:owlapi-api + net.sourceforge.owlapi:owlapi-apibinding + net.sourceforge.owlapi:owlapi-compatibility + net.sourceforge.owlapi:owlapi-impl + net.sourceforge.owlapi:owlapi-parsers + net.sourceforge.owlapi:owlapi-oboformat + net.sourceforge.owlapi:owlapi-rio + net.sourceforge.owlapi:owlapi-tools + + From 46c14b4c83350fe7dcbc76641269667ce06703c0 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 16:28:16 +0100 Subject: [PATCH 156/280] Reenable deletion of temp files in tests --- ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java b/ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java index 54af7f7b..e4a876cf 100644 --- a/ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java +++ b/ret-cli/src/test/java/de/atextor/ret/cli/RetTest.java @@ -58,13 +58,13 @@ void beforeEach() throws IOException { @AfterEach void afterEach() throws IOException { -// FileUtils.deleteDirectory( tempDir.toFile() ); + FileUtils.deleteDirectory( tempDir.toFile() ); } @AfterAll static void afterAll() throws IOException { if ( tempDir != null && tempDir.toFile().exists() ) { -// FileUtils.deleteDirectory( tempDir.toFile() ); + FileUtils.deleteDirectory( tempDir.toFile() ); } } From 5ce1264dc5c8a57e973f9179eba4008e98751c85 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 16:28:37 +0100 Subject: [PATCH 157/280] Reuse jar file name in ret-cli pom --- ret-cli/pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ret-cli/pom.xml b/ret-cli/pom.xml index 6ecfe976..67b53634 100644 --- a/ret-cli/pom.xml +++ b/ret-cli/pom.xml @@ -161,8 +161,7 @@ - ${project.build.directory}/${project.artifactId}-${project.version}.jar - + ${project.build.directory}/${regular-jar}.jar ${project.build.directory}/${binary-name} 1 From df8b1e8807ccf9b1a51393a0e2eefc573a379c42 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 21:06:14 +0100 Subject: [PATCH 158/280] Update copyright headers --- docs/modules/ROOT/assets/images/splash.svg | 16 +++++++++ pom.xml | 16 +++++++++ ret-cli/pom.xml | 16 +++++++++ .../de/atextor/ret/cli/AbstractCommand.java | 4 +-- .../java/de/atextor/ret/cli/ErrorMessage.java | 4 +-- .../java/de/atextor/ret/cli/LoggingMixin.java | 4 +-- .../src/main/java/de/atextor/ret/cli/Ret.java | 4 +-- .../java/de/atextor/ret/cli/RetDiagram.java | 4 +-- .../java/de/atextor/ret/cli/RetInfer.java | 4 +-- .../java/de/atextor/ret/cli/RetWrite.java | 4 +-- ...module_SubsystemRegistryServiceLoader.java | 4 +-- ..._riot_system_stream_JenaIOEnvironment.java | 4 +-- ..._org_apache_jena_util_FileManagerImpl.java | 4 +-- ...t_org_apache_jena_util_LocationMapper.java | 4 +-- .../de.atextor/owlcli/native-image.properties | 2 +- ret-cli/src/main/resources/logback.xml | 2 +- .../java/de/atextor/ret/cli/CliRunner.java | 2 +- .../ret/cli/ResourceArgumentsProvider.java | 4 +-- ret-core/pom.xml | 16 +++++++++ .../buildtime/StringTemplate.java | 16 +++++++++ .../buildtime/WriteVersionClass.java | 2 +- ret-diagram-owl/pom.xml | 16 +++++++++ .../ret/diagram/owl/Configuration.java | 4 +-- .../ret/diagram/owl/DiagramGenerator.java | 16 ++++----- .../atextor/ret/diagram/owl/FontEmbedder.java | 4 +-- .../ret/diagram/owl/GraphvizDocument.java | 6 ++-- .../ret/diagram/owl/GraphvizGenerator.java | 8 ++--- .../de/atextor/ret/diagram/owl/Template.java | 4 +-- .../ret/diagram/owl/ThrowingConsumer.java | 4 +-- .../atextor/ret/diagram/owl/graph/Edge.java | 4 +-- .../atextor/ret/diagram/owl/graph/Graph.java | 5 +-- .../ret/diagram/owl/graph/GraphElement.java | 4 +-- .../ret/diagram/owl/graph/GraphVisitor.java | 6 ++-- .../atextor/ret/diagram/owl/graph/Node.java | 5 +-- .../owl/graph/node/AnnotationProperty.java | 5 +-- .../ret/diagram/owl/graph/node/Class.java | 5 +-- .../diagram/owl/graph/node/ClosedClass.java | 4 +-- .../diagram/owl/graph/node/Complement.java | 4 +-- .../owl/graph/node/DataExactCardinality.java | 5 +-- .../graph/node/DataMaximalCardinality.java | 5 +-- .../graph/node/DataMinimalCardinality.java | 5 +-- .../diagram/owl/graph/node/DataProperty.java | 5 +-- .../ret/diagram/owl/graph/node/Datatype.java | 5 +-- .../diagram/owl/graph/node/DisjointUnion.java | 4 +-- .../diagram/owl/graph/node/Disjointness.java | 4 +-- .../ret/diagram/owl/graph/node/Equality.java | 4 +-- .../graph/node/ExistentialRestriction.java | 4 +-- .../diagram/owl/graph/node/IRIReference.java | 4 +-- .../diagram/owl/graph/node/Individual.java | 5 +-- .../diagram/owl/graph/node/Inequality.java | 4 +-- .../diagram/owl/graph/node/Intersection.java | 4 +-- .../ret/diagram/owl/graph/node/Inverse.java | 4 +-- .../ret/diagram/owl/graph/node/Invisible.java | 4 +-- .../ret/diagram/owl/graph/node/Key.java | 4 +-- .../ret/diagram/owl/graph/node/Literal.java | 5 +-- .../graph/node/ObjectExactCardinality.java | 5 +-- .../graph/node/ObjectMaximalCardinality.java | 5 +-- .../graph/node/ObjectMinimalCardinality.java | 5 +-- .../owl/graph/node/ObjectProperty.java | 5 +-- .../node/ObjectQualifiedExactCardinality.java | 5 +-- .../ObjectQualifiedMaximalCardinality.java | 5 +-- .../ObjectQualifiedMinimalCardinality.java | 5 +-- .../diagram/owl/graph/node/PropertyChain.java | 5 +-- .../owl/graph/node/PropertyMarker.java | 5 +-- .../ret/diagram/owl/graph/node/Rule.java | 6 ++-- .../ret/diagram/owl/graph/node/Self.java | 4 +-- .../ret/diagram/owl/graph/node/Union.java | 4 +-- .../owl/graph/node/UniversalRestriction.java | 4 +-- .../owl/graph/node/ValueRestriction.java | 4 +-- .../owl/graph/transformer/ChangeSet.java | 5 +-- .../graph/transformer/GraphTransformer.java | 10 +++--- .../transformer/IriReferenceResolver.java | 4 +-- .../transformer/PropertyMarkerMerger.java | 4 +-- .../owl/graph/transformer/PunningRemover.java | 6 ++-- .../owl/mappers/DefaultIdentifierMapper.java | 4 +-- .../mappers/DefaultMappingConfiguration.java | 34 +++++++++++++++++-- .../owl/mappers/DefaultNameMapper.java | 4 +-- .../diagram/owl/mappers/IdentifierMapper.java | 4 +-- .../owl/mappers/MappingConfiguration.java | 4 +-- .../ret/diagram/owl/mappers/NameMapper.java | 4 +-- .../mappers/OWLAnnotationObjectMapper.java | 4 +-- .../diagram/owl/mappers/OWLAxiomMapper.java | 18 +++++----- .../owl/mappers/OWLClassExpressionMapper.java | 12 +++---- .../diagram/owl/mappers/OWLDataMapper.java | 6 ++-- .../diagram/owl/mappers/OWLEntityMapper.java | 4 +-- .../owl/mappers/OWLIndividualMapper.java | 4 +-- .../diagram/owl/mappers/OWLObjectMapper.java | 4 +-- .../owl/mappers/OWLOntologyMapper.java | 5 +-- .../mappers/OWLPropertyExpressionMapper.java | 4 +-- .../diagram/owl/mappers/SWRLObjectMapper.java | 6 ++-- .../printers/OWLClassExpressionPrinter.java | 4 +-- .../diagram/owl/printers/OWLDataPrinter.java | 4 +-- .../owl/printers/OWLIndividualPrinter.java | 4 +-- .../OWLPropertyExpressionPrinter.java | 4 +-- .../ret/diagram/owl/DiagramGeneratorTest.java | 4 +-- .../diagram/owl/GraphvizGeneratorTest.java | 9 +++-- .../ret/diagram/owl/MapperTestBase.java | 6 ++-- .../owl/OWLAnnotationObjectMapperTest.java | 4 +-- .../ret/diagram/owl/OWLAxiomMapperTest.java | 23 +++++++------ .../owl/OWLClassExpressionMapperTest.java | 4 +-- .../ret/diagram/owl/OWLDataMapperTest.java | 4 +-- .../ret/diagram/owl/OWLEntityMapperTest.java | 4 +-- .../diagram/owl/OWLIndividualMapperTest.java | 4 +-- .../diagram/owl/OWLOntologyMapperTest.java | 5 +-- .../owl/OWLPropertyExpressionMapperTest.java | 4 +-- .../ret/diagram/owl/SWRLObjectMapperTest.java | 5 +-- .../ret/diagram/owl/TestIdentifierMapper.java | 4 +-- .../ret/diagram/owl/TestNameMapper.java | 4 +-- ret-infer/pom.xml | 16 +++++++++ .../de/atextor/ret/infer/Configuration.java | 4 +-- .../java/de/atextor/ret/infer/Inferrer.java | 4 +-- .../de/atextor/ret/infer/InferrerTest.java | 4 +-- ret-write/pom.xml | 16 +++++++++ .../de/atextor/ret/write/Configuration.java | 4 +-- .../java/de/atextor/ret/write/RdfWriter.java | 4 +-- .../de/atextor/ret/write/RdfWriterTest.java | 4 +-- scripts/do-release.sh | 4 +-- 117 files changed, 441 insertions(+), 251 deletions(-) diff --git a/docs/modules/ROOT/assets/images/splash.svg b/docs/modules/ROOT/assets/images/splash.svg index a00a7b44..4d0c8f18 100644 --- a/docs/modules/ROOT/assets/images/splash.svg +++ b/docs/modules/ROOT/assets/images/splash.svg @@ -1,4 +1,20 @@ + + + + 4.0.0 diff --git a/ret-cli/pom.xml b/ret-cli/pom.xml index 67b53634..0047d371 100644 --- a/ret-cli/pom.xml +++ b/ret-cli/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java index 3d90d5de..10c1ae93 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java b/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java index 5016b75b..9b6356c2 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java index 116c42e3..c8e3f393 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java b/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java index 58a7acbb..5296cc45 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java index 61ca30fa..9f01e457 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java index 7a35eca3..ae2868cc 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java index 6dedba30..45593db2 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java index c889617a..b39d3b3d 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java index 2d73eed7..f3c6bd08 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_riot_system_stream_JenaIOEnvironment.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java index d7efdcc2..cdab0f3f 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_LocationMapper.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_LocationMapper.java index 9408c357..f5e9619c 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_LocationMapper.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_LocationMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2022 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties index b8656e27..8e3bce35 100644 --- a/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties +++ b/ret-cli/src/main/resources/META-INF/native-image/de.atextor/owlcli/native-image.properties @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-cli/src/main/resources/logback.xml b/ret-cli/src/main/resources/logback.xml index a0cb59ae..e34d9f52 100644 --- a/ret-cli/src/main/resources/logback.xml +++ b/ret-cli/src/main/resources/logback.xml @@ -1,5 +1,5 @@ + diff --git a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java index 8532131c..77dde8c2 100644 --- a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java +++ b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java @@ -1,3 +1,19 @@ +/* + * Copyright 2024 Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package de.atextor.ret.core.buildtime; import java.util.Map; diff --git a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java index c820da5b..85518c4d 100644 --- a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java +++ b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/ret-diagram-owl/pom.xml b/ret-diagram-owl/pom.xml index aa68ea12..24a71686 100644 --- a/ret-diagram-owl/pom.xml +++ b/ret-diagram-owl/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Configuration.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Configuration.java index 3f7ee4fe..d8e525d2 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Configuration.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Configuration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java index 9319e51f..163ef647 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -69,9 +69,9 @@ private Try writeStreamToOutput( final InputStream in, final OutputStream } Try executeDot( final ThrowingConsumer contentProvider, - final OutputStream output, - final File workingDir, - final Configuration configuration ) { + final OutputStream output, + final File workingDir, + final Configuration configuration ) { final String command = configuration.dotBinary + " -T" + configuration.format.getExtension(); final Process process; try { @@ -129,13 +129,13 @@ private Try postProcess( final String dotOutput ) { * Performs diagram generation for an input ontology. The result is either written to a given {@link OutputStream} * or a given {@link Path}. * - * @param ontology the input ontology - * @param output the output to write + * @param ontology the input ontology + * @param output the output to write * @param configuration the configuration for the diagram generation * @return {@link io.vavr.control.Try.Success} on success */ public Try generate( final OWLOntology ontology, final OutputStream output, - final Configuration configuration ) { + final Configuration configuration ) { LOG.info( "Applying ontology mappers" ); final Stream ontologyGraphRepresenation = ontologyMapper.apply( ontology ).stream(); LOG.info( "Generating Graphviz document" ); diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java index fcf68e3d..54bc5381 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java index 0ece62de..e72742cd 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -130,7 +130,7 @@ public String toString() { '}'; } - record Statement(String content) { + record Statement( String content ) { String toFragment() { return content + "\n"; } diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java index a71bdc22..eeaf16dc 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -101,7 +101,7 @@ public class GraphvizGenerator implements Function, Graphvi final String edgeStyle = edgeTypeToGraphviz( edge.getType() ) .map( style -> String.format( "%s, fontsize=%d, fontname=\"%s\", color=\"%s\", fontcolor=\"%s\"", style, configuration.fontsize, configuration.fontname, configuration.fgColor, - configuration.fgColor ) ) + configuration.fgColor ) ) .orElse( "" ); return GraphvizDocument.withEdge( new GraphvizDocument.Statement( String.format( "%s -> %s [%s]", escapeNodeId( edge.getFrom().getId() ), @@ -186,7 +186,7 @@ private enum Symbol { * Returns a DOT fragment for an element with this symbol. Note that the referenced font 'owlcli' * is injected during rendering using the {@link FontEmbedder}. * - * @param elementName the name of the element + * @param elementName the name of the element * @param configuration the diagram generation configuration * @return the dot fragment for this element */ diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java index 355a1eed..8ae651c1 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/ThrowingConsumer.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/ThrowingConsumer.java index 3bf43dc9..a0b98c45 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/ThrowingConsumer.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/ThrowingConsumer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Edge.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Edge.java index c6d6a497..577e884e 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Edge.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Edge.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Graph.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Graph.java index 3271bb7d..52169271 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Graph.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Graph.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -28,6 +28,7 @@ @Getter public class Graph { final Node node; + final Stream otherElements; protected Graph( final Node node, final Stream otherElements ) { diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphElement.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphElement.java index 62557ca1..70bd488a 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphElement.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphElement.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphVisitor.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphVisitor.java index ecf94cf6..a68b9c4d 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphVisitor.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/GraphVisitor.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,7 +31,9 @@ @FieldDefaults( makeFinal = true, level = AccessLevel.PRIVATE ) public class GraphVisitor implements GraphElement.Visitor { Node.Visitor nodeTypeVisitor; + Function plainEdgeHandler; + Function decoratedEdgeHandler; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Node.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Node.java index 105dd14f..dea6853e 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Node.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/Node.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -153,6 +153,7 @@ public interface Visitor { @EqualsAndHashCode public static class Id { final String id; + final Optional iri; public Id( final String id, final IRI iri ) { diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/AnnotationProperty.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/AnnotationProperty.java index f7bbafce..8cc8e3f4 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/AnnotationProperty.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/AnnotationProperty.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class AnnotationProperty extends Node.NamedNode { Id id; + String name; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Class.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Class.java index 53ec6c81..8abee38b 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Class.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Class.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class Class extends Node.NamedNode { Id id; + String name; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ClosedClass.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ClosedClass.java index 719b61de..9c5777cc 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ClosedClass.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ClosedClass.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Complement.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Complement.java index 0b2f841d..0758929f 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Complement.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Complement.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataExactCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataExactCardinality.java index 8759f5d4..849bc1cb 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataExactCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataExactCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class DataExactCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMaximalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMaximalCardinality.java index 900ba036..3a80a321 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMaximalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMaximalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class DataMaximalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMinimalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMinimalCardinality.java index 72eafc91..32b387f8 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMinimalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataMinimalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class DataMinimalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataProperty.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataProperty.java index 3c9579bf..fb323ebf 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataProperty.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DataProperty.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class DataProperty extends Node.NamedNode { Id id; + String name; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Datatype.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Datatype.java index 681f1f5f..1dd1b2bb 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Datatype.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Datatype.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class Datatype extends Node.NamedNode { Id id; + String name; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DisjointUnion.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DisjointUnion.java index f68ac8ed..fa152c4d 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DisjointUnion.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/DisjointUnion.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Disjointness.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Disjointness.java index c62c1855..aef1aa59 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Disjointness.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Disjointness.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Equality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Equality.java index 552da5f1..018e0523 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Equality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Equality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ExistentialRestriction.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ExistentialRestriction.java index dc4dc805..c4d635b0 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ExistentialRestriction.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ExistentialRestriction.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/IRIReference.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/IRIReference.java index bac3e6bf..ab6f494f 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/IRIReference.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/IRIReference.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Individual.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Individual.java index 36aaef7d..f7ca19a4 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Individual.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Individual.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class Individual extends Node.NamedNode { Id id; + String name; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inequality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inequality.java index b6e3249e..cec6741b 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inequality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inequality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Intersection.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Intersection.java index a2501c61..e9bbe404 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Intersection.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Intersection.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inverse.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inverse.java index a0f87c72..2e181cf2 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inverse.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Inverse.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Invisible.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Invisible.java index 1576fbe3..6d0461bd 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Invisible.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Invisible.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Key.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Key.java index 1f6f6d81..4fddf00c 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Key.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Key.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Literal.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Literal.java index cd4786b2..4e486577 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Literal.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Literal.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class Literal extends Node { Id id; + String value; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectExactCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectExactCardinality.java index b50ae94d..332c202c 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectExactCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectExactCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class ObjectExactCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMaximalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMaximalCardinality.java index 4dcc582e..c04328bf 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMaximalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMaximalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class ObjectMaximalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMinimalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMinimalCardinality.java index ba536512..b9df5609 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMinimalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectMinimalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class ObjectMinimalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectProperty.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectProperty.java index c7e147f4..edaca75b 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectProperty.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectProperty.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class ObjectProperty extends Node.NamedNode { Id id; + String name; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java index f8242a55..24389f6e 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class ObjectQualifiedExactCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java index 3d89da13..e8ccb851 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class ObjectQualifiedMaximalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java index b76e8621..6ef4c6c7 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +29,7 @@ @With public class ObjectQualifiedMinimalCardinality extends Node.CardinalityNode { Id id; + int cardinality; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyChain.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyChain.java index 554f69c4..442740c9 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyChain.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyChain.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,6 +31,7 @@ public class PropertyChain extends Node { public static final String OPERATOR_SYMBOL = "o"; Id id; + String value; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyMarker.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyMarker.java index 9f77569c..0128d09a 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyMarker.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/PropertyMarker.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -42,6 +42,7 @@ public enum Kind { } Id id; + Set kind; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Rule.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Rule.java index bc0048f8..58f96b9d 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Rule.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Rule.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,9 +29,11 @@ @With public class Rule extends Node { public static final String CONJUNCTION_SYMBOL = "∧"; + public static final String IMPLICATION_SYMBOL = "⇒"; Id id; + String value; @Override diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Self.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Self.java index 6a458397..39136974 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Self.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Self.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Union.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Union.java index 9ba2b475..c1893140 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Union.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/Union.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/UniversalRestriction.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/UniversalRestriction.java index 5daa18fb..ecd60de9 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/UniversalRestriction.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/UniversalRestriction.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ValueRestriction.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ValueRestriction.java index 04b606cd..785da3f8 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ValueRestriction.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/node/ValueRestriction.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/ChangeSet.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/ChangeSet.java index 98b04aae..a42fcf4a 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/ChangeSet.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/ChangeSet.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -30,6 +30,7 @@ class ChangeSet { public static final ChangeSet EMPTY = new ChangeSet( Set.of(), Set.of() ); Set additions; + Set deletions; /** diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/GraphTransformer.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/GraphTransformer.java index cd43ce06..102ac02c 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/GraphTransformer.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/GraphTransformer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -42,14 +42,12 @@ protected ChangeSet updateEdgesTo( final Set graph, final Node old return updateEdge( graph, oldToNode, newToNode, Edge::getTo, Edge::setTo ); } - protected ChangeSet updateEdgesFrom( final Set graph, final Node oldFromNode, - final Node newFromNode ) { + protected ChangeSet updateEdgesFrom( final Set graph, final Node oldFromNode, final Node newFromNode ) { return updateEdge( graph, oldFromNode, newFromNode, Edge::getFrom, Edge::setFrom ); } private ChangeSet updateEdge( final Set graph, final Node oldNode, final Node newNode, - final Function getter, - final BiFunction setter ) { + final Function getter, final BiFunction setter ) { return graph.stream() .filter( GraphElement::isEdge ) .map( GraphElement::asEdge ) diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/IriReferenceResolver.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/IriReferenceResolver.java index 39415da7..3fac27d0 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/IriReferenceResolver.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/IriReferenceResolver.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PropertyMarkerMerger.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PropertyMarkerMerger.java index 02bfc318..a9c5d500 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PropertyMarkerMerger.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PropertyMarkerMerger.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PunningRemover.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PunningRemover.java index 4c9464ad..9080217c 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PunningRemover.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/graph/transformer/PunningRemover.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -82,7 +82,7 @@ private Stream updateNode( final Set graph, final Node private Node.Id buildNewNodeId( final Node.Id original ) { return original.getIri().map( iri -> - mappingConfiguration.getIdentifierMapper().getSyntheticIdForIri( iri ) ) + mappingConfiguration.getIdentifierMapper().getSyntheticIdForIri( iri ) ) .orElseGet( () -> mappingConfiguration.getIdentifierMapper().getSyntheticId() ); } } diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultIdentifierMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultIdentifierMapper.java index e273668f..3b7b7503 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultIdentifierMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultIdentifierMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultMappingConfiguration.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultMappingConfiguration.java index 37dbcfde..32537c98 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultMappingConfiguration.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultMappingConfiguration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -36,20 +36,35 @@ public class DefaultMappingConfiguration implements MappingConfiguration { private OWLAxiomVisitorEx owlAxiomMapper; + private OWLClassExpressionVisitorEx owlClassExpressionMapper; + private OWLIndividualVisitorEx owlIndividualMapper; + private OWLPropertyExpressionVisitorEx owlPropertyExpressionMapper; + private OWLObjectVisitorEx owlObjectMapper; + private OWLDataVisitorEx owlDataMapper; + private OWLEntityVisitorEx owlEntityMapper; + private OWLAnnotationObjectVisitorEx owlAnnotationObjectMapper; + private OWLAnnotationSubjectVisitorEx owlAnnotationSubjectMapper; + private SWRLObjectVisitorEx swrlObjectMapper; + private IdentifierMapper identifierMapper; + private NameMapper nameMapper; + private OWLDataVisitorEx owlDataPrinter; + private OWLPropertyExpressionVisitorEx owlPropertyExpressionPrinter; + private OWLIndividualVisitorEx owlIndividualPrinter; + private OWLClassExpressionVisitorEx owlClassExpressionPrinter; private DefaultMappingConfiguration() { @@ -205,20 +220,35 @@ public static Builder builder() { public static class Builder { private Optional> owlAxiomMapper = Optional.empty(); + private Optional> owlClassExpressionMapper = Optional.empty(); + private Optional> owlIndividualMapper = Optional.empty(); + private Optional> owlPropertyExpressionMapper = Optional.empty(); + private Optional> owlObjectMapper = Optional.empty(); + private Optional> owlDataMapper = Optional.empty(); + private Optional> owlEntityMapper = Optional.empty(); + private Optional> owlAnnotationObjectMapper = Optional.empty(); + private Optional> owlAnnotationSubjectMapper = Optional.empty(); + private Optional> swrlObjectMapper = Optional.empty(); + private Optional identifierMapper = Optional.empty(); + private Optional nameMapper = Optional.empty(); + private Optional> owlDataPrinter = Optional.empty(); + private Optional> owlPropertyExpressionPrinter = Optional.empty(); + private Optional> owlIndividualPrinter = Optional.empty(); + private Optional> owlClassExpressionPrinter = Optional.empty(); public Builder owlAxiomMapper( final OWLAxiomVisitorEx mapper ) { diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultNameMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultNameMapper.java index 12aaa896..3bba1c83 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultNameMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/DefaultNameMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/IdentifierMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/IdentifierMapper.java index 874db5f4..1f1232ff 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/IdentifierMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/IdentifierMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/MappingConfiguration.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/MappingConfiguration.java index 92de491f..7abde460 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/MappingConfiguration.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/MappingConfiguration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/NameMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/NameMapper.java index 95770ace..25453eb4 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/NameMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/NameMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAnnotationObjectMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAnnotationObjectMapper.java index 7fc52379..9578f94f 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAnnotationObjectMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAnnotationObjectMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAxiomMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAxiomMapper.java index d72278fa..7511e2c7 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAxiomMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLAxiomMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -126,7 +126,7 @@ public Graph visit( final @Nonnull OWLSubClassOfAxiom axiom ) { private

Stream propertyStructure( final OWLPropertyAssertionAxiom axiom, final Node thirdNode, - final Edge.Type subjectToThirdNodeType ) { + final Edge.Type subjectToThirdNodeType ) { final Graph subjectGraph = axiom.getSubject().accept( mappingConfig.getOwlIndividualMapper() ); final Graph propertyGraph = axiom.getProperty().accept( mappingConfig.getOwlPropertyExpressionMapper() ); @@ -249,7 +249,7 @@ public Graph visit( final @Nonnull OWLSubObjectPropertyOfAxiom axiom ) { } private Graph linkNodeToMultipleOthers( final HasOperands axiom, - final Node fromNode ) { + final Node fromNode ) { return axiom.operands().map( operand -> { final Graph operandGraph = operand.accept( mappingConfig.getOwlObjectMapper() ); final Edge fromNodeToOperandEdge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, fromNode, operandGraph @@ -279,7 +279,7 @@ public Graph visit( final @Nonnull OWLDataPropertyRangeAxiom axiom ) { } private Graph propertyMarker( final OWLPropertyExpression propertyExpression, - final PropertyMarker.Kind markerKind ) { + final PropertyMarker.Kind markerKind ) { final Node marker = new PropertyMarker( mappingConfig.getIdentifierMapper().getSyntheticId(), Set.of( markerKind ) ); final Node propertyNode = propertyExpression.accept( mappingConfig.getOwlPropertyExpressionMapper() ).getNode(); @@ -296,11 +296,11 @@ public Graph visit( final @Nonnull OWLFunctionalDataPropertyAxiom axiom ) { * Shared logic for axioms that generate sets of nodes that are pairwise equivalent, * e.g. {@link org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom}s. * - * @param axiom The axiom to generate results for + * @param axiom The axiom to generate results for * @param visitor The visitor that handles the type of axiom - * @param The type of object the axiom describes - * @param The axiom type - * @param The type of visitor that handles the axiom type + * @param The type of object the axiom describes + * @param The axiom type + * @param The type of visitor that handles the axiom type * @return the graph representing the equivalency */ private , V extends OWLObjectVisitorEx> diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLClassExpressionMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLClassExpressionMapper.java index 03d235d6..e7a2c12d 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLClassExpressionMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLClassExpressionMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -82,7 +82,7 @@ public OWLClassExpressionMapper( final MappingConfiguration mappingConfig ) { } private Stream createEdgeToClassExpression( final Node sourceNode, - final OWLClassExpression classExpression ) { + final OWLClassExpression classExpression ) { final Graph diagramPartsForClassExpression = classExpression.accept( this ); final Node targetNode = diagramPartsForClassExpression.getNode(); final Stream remainingElements = diagramPartsForClassExpression.getOtherElements(); @@ -116,7 +116,7 @@ public Graph visit( final @Nonnull OWLObjectComplementOf classExpression ) { } private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, - final OWLQuantifiedObjectRestriction classExpression ) { + final OWLQuantifiedObjectRestriction classExpression ) { final OWLClassExpression c = classExpression.getFiller(); final OWLObjectPropertyExpression r = classExpression.getProperty(); final Graph cNodeGraph = c.accept( mappingConfig.getOwlClassExpressionMapper() ); @@ -130,7 +130,7 @@ private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, } private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, - final OWLQuantifiedDataRestriction classExpression ) { + final OWLQuantifiedDataRestriction classExpression ) { final OWLDataRange u = classExpression.getFiller(); final OWLDataPropertyExpression d = classExpression.getProperty(); final Graph uNodeGraph = u.accept( mappingConfig.getOwlDataMapper() ); @@ -143,7 +143,7 @@ private Graph createPropertyAndObjectRangeEdges( final Node restrictionNode, } private Graph createPropertyEdge( final Node restrictionNode, final OWLRestriction classExpression, - final Edge.Decorated.Label edgeLabel ) { + final Edge.Decorated.Label edgeLabel ) { final OWLPropertyExpression property = classExpression.getProperty(); final Graph rNodeGraph = property.accept( mappingConfig.getOwlPropertyExpressionMapper() ); final Edge rEdge = new Edge.Decorated( Edge.Type.DEFAULT_ARROW, restrictionNode, rNodeGraph diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLDataMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLDataMapper.java index 98da3b41..d3c2295a 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLDataMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLDataMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -50,7 +50,7 @@ public OWLDataMapper( final MappingConfiguration mappingConfig ) { } private Stream createEdgeToDataRange( final Node sourceNode, - final OWLDataRange classExpression ) { + final OWLDataRange classExpression ) { final Graph diagramPartsForDataRange = classExpression.accept( this ); final Node targetNode = diagramPartsForDataRange.getNode(); final Stream remainingElements = diagramPartsForDataRange.getOtherElements(); diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLEntityMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLEntityMapper.java index 27b29d72..7f86aa0b 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLEntityMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLEntityMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLIndividualMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLIndividualMapper.java index d17fcf7e..508089e2 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLIndividualMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLIndividualMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLObjectMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLObjectMapper.java index a3d08552..c80cf264 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLObjectMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLObjectMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLOntologyMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLOntologyMapper.java index 71c1f8a3..b66aa2f9 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLOntologyMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLOntologyMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -36,6 +36,7 @@ */ public class OWLOntologyMapper implements Function> { private final MappingConfiguration mappingConfiguration; + private final List, Set>> transformers; public OWLOntologyMapper( final MappingConfiguration mappingConfiguration ) { diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLPropertyExpressionMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLPropertyExpressionMapper.java index 79909f3f..4ebdd6b9 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLPropertyExpressionMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/OWLPropertyExpressionMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/SWRLObjectMapper.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/SWRLObjectMapper.java index 319c5598..cedbd64d 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/SWRLObjectMapper.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/mappers/SWRLObjectMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -115,7 +115,7 @@ public Graph visit( final @Nonnull SWRLObjectPropertyAtom atom ) { } private Graph visitPropertyAtom( final SWRLBinaryAtom atom, - final OWLPropertyExpression predicate ) { + final OWLPropertyExpression predicate ) { final List argumentGraphElements = argumentElements( atom ); final String arguments = printArgumentElements( argumentGraphElements ); diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLClassExpressionPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLClassExpressionPrinter.java index 351d2ae6..f71d18b3 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLClassExpressionPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLClassExpressionPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLDataPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLDataPrinter.java index 8502593c..b1f914ee 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLDataPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLDataPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLIndividualPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLIndividualPrinter.java index 1d7d055b..2ec855a3 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLIndividualPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLIndividualPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLPropertyExpressionPrinter.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLPropertyExpressionPrinter.java index e375a07b..de017dc3 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLPropertyExpressionPrinter.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/printers/OWLPropertyExpressionPrinter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/DiagramGeneratorTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/DiagramGeneratorTest.java index 6e31cc3e..2f9470ba 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/DiagramGeneratorTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/DiagramGeneratorTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/GraphvizGeneratorTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/GraphvizGeneratorTest.java index 20468a35..46fc9477 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/GraphvizGeneratorTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/GraphvizGeneratorTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -58,10 +58,15 @@ public class GraphvizGeneratorTest { final GraphvizGenerator generator = new GraphvizGenerator( Configuration.builder().build() ); + final Node.Id from1 = new Node.Id( "foo" ); + final Node.Id to1 = new Node.Id( "bar" ); + final String name1 = "baz"; + final int cardinality1 = 5; + final String value1 = "theValue"; Predicate contains( final String needle ) { diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/MapperTestBase.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/MapperTestBase.java index ca20f505..f2c73e77 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/MapperTestBase.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/MapperTestBase.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -167,7 +167,7 @@ protected Predicate isEdgeWithFromAndTo( final String fromId, final String } protected Predicate isEdgeWithFromAndToAndLabel( final String fromId, final String toId, - final Edge.Decorated.Label label ) { + final Edge.Decorated.Label label ) { return edge -> edge.getFrom().getId().getId().equals( fromId ) && edge.getTo().getId().getId().equals( toId ) && ( (Edge.Decorated) edge ).getLabel().equals( label ); diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAnnotationObjectMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAnnotationObjectMapperTest.java index e5d2ffdc..500e58fb 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAnnotationObjectMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAnnotationObjectMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAxiomMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAxiomMapperTest.java index 7bb3b1d9..e9d221e5 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAxiomMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLAxiomMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -78,6 +78,7 @@ public class OWLAxiomMapperTest extends MapperTestBase { private final MappingConfiguration mappingConfiguration = createTestMappingConfiguration(); + private final OWLAxiomMapper mapper = new OWLAxiomMapper( mappingConfiguration ); @Test @@ -156,7 +157,7 @@ public void testOWLAsymmetricObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.ASYMMETRIC ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.ASYMMETRIC ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -179,7 +180,7 @@ public void testOWLReflexiveObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.REFLEXIVE ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.REFLEXIVE ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -500,7 +501,7 @@ public void testOWLFunctionalObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -577,7 +578,7 @@ public void testOWLSymmetricObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.SYMMETRIC ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.SYMMETRIC ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -624,7 +625,7 @@ public void testOWLFunctionalDataPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.FUNCTIONAL ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -770,7 +771,7 @@ public void testOWLTransitiveObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.TRANSITIVE ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.TRANSITIVE ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -793,7 +794,7 @@ public void testOWLIrreflexiveObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.IRREFLEXIVE ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.IRREFLEXIVE ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -841,7 +842,7 @@ public void testOWLInverseFunctionalObjectPropertyAxiom() { assertThat( nodes ).hasSize( 2 ); assertThat( nodes ).anyMatch( isNodeWithId( "foo" ) ); assertThat( nodes ).anyMatch( node -> node.view( PropertyMarker.class ).map( propertyMarker -> - propertyMarker.getKind().contains( PropertyMarker.Kind.INVERSE_FUNCTIONAL ) ).findFirst() + propertyMarker.getKind().contains( PropertyMarker.Kind.INVERSE_FUNCTIONAL ) ).findFirst() .orElse( false ) ); final List edges = edges( result ); @@ -1031,7 +1032,7 @@ public void testOWLAnnotationPropertyRangeAxiom() { } private void assertEquivalentResult( final Set result, final IRI fooIri, final IRI barIri, - final IRI bazIri ) { + final IRI bazIri ) { final List nodes = nodes( result ); assertThat( nodes ).hasSize( 3 ); diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLClassExpressionMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLClassExpressionMapperTest.java index ad871d00..ab5604d1 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLClassExpressionMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLClassExpressionMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLDataMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLDataMapperTest.java index 6f787e4a..af352ea8 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLDataMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLDataMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLEntityMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLEntityMapperTest.java index ab0ca372..78ac1c66 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLEntityMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLEntityMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLIndividualMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLIndividualMapperTest.java index cb806490..83e0a75b 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLIndividualMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLIndividualMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLOntologyMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLOntologyMapperTest.java index bc8db013..8f24fa27 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLOntologyMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLOntologyMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -34,6 +34,7 @@ public class OWLOntologyMapperTest extends MapperTestBase { private final MappingConfiguration mappingConfiguration = DefaultMappingConfiguration.builder().build(); + private final OWLOntologyMapper mapper = new OWLOntologyMapper( mappingConfiguration ); @Test diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLPropertyExpressionMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLPropertyExpressionMapperTest.java index d74520ae..9e0e9283 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLPropertyExpressionMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/OWLPropertyExpressionMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/SWRLObjectMapperTest.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/SWRLObjectMapperTest.java index a5ee44a0..004160af 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/SWRLObjectMapperTest.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/SWRLObjectMapperTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -34,6 +34,7 @@ public class SWRLObjectMapperTest extends MapperTestBase { private final MappingConfiguration mappingConfiguration = createTestMappingConfiguration(); + private final OWLAxiomMapper mapper = new OWLAxiomMapper( mappingConfiguration ); @Test diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestIdentifierMapper.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestIdentifierMapper.java index a7f89634..e7eb86a1 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestIdentifierMapper.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestIdentifierMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestNameMapper.java b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestNameMapper.java index 759a6806..71648c53 100644 --- a/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestNameMapper.java +++ b/ret-diagram-owl/src/test/java/de/atextor/ret/diagram/owl/TestNameMapper.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-infer/pom.xml b/ret-infer/pom.xml index b150c1de..f1b60084 100644 --- a/ret-infer/pom.xml +++ b/ret-infer/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/ret-infer/src/main/java/de/atextor/ret/infer/Configuration.java b/ret-infer/src/main/java/de/atextor/ret/infer/Configuration.java index 6d7dab18..80cd72d4 100644 --- a/ret-infer/src/main/java/de/atextor/ret/infer/Configuration.java +++ b/ret-infer/src/main/java/de/atextor/ret/infer/Configuration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-infer/src/main/java/de/atextor/ret/infer/Inferrer.java b/ret-infer/src/main/java/de/atextor/ret/infer/Inferrer.java index 48fc2de6..7063d47e 100644 --- a/ret-infer/src/main/java/de/atextor/ret/infer/Inferrer.java +++ b/ret-infer/src/main/java/de/atextor/ret/infer/Inferrer.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-infer/src/test/java/de/atextor/ret/infer/InferrerTest.java b/ret-infer/src/test/java/de/atextor/ret/infer/InferrerTest.java index 92839f5b..95e583c0 100644 --- a/ret-infer/src/test/java/de/atextor/ret/infer/InferrerTest.java +++ b/ret-infer/src/test/java/de/atextor/ret/infer/InferrerTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-write/pom.xml b/ret-write/pom.xml index 8bf3ea88..fea9e776 100644 --- a/ret-write/pom.xml +++ b/ret-write/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/ret-write/src/main/java/de/atextor/ret/write/Configuration.java b/ret-write/src/main/java/de/atextor/ret/write/Configuration.java index a69bf7dc..1da9cc8f 100644 --- a/ret-write/src/main/java/de/atextor/ret/write/Configuration.java +++ b/ret-write/src/main/java/de/atextor/ret/write/Configuration.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-write/src/main/java/de/atextor/ret/write/RdfWriter.java b/ret-write/src/main/java/de/atextor/ret/write/RdfWriter.java index e828441b..bed1c675 100644 --- a/ret-write/src/main/java/de/atextor/ret/write/RdfWriter.java +++ b/ret-write/src/main/java/de/atextor/ret/write/RdfWriter.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/ret-write/src/test/java/de/atextor/ret/write/RdfWriterTest.java b/ret-write/src/test/java/de/atextor/ret/write/RdfWriterTest.java index 3fe6429b..b7e87017 100644 --- a/ret-write/src/test/java/de/atextor/ret/write/RdfWriterTest.java +++ b/ret-write/src/test/java/de/atextor/ret/write/RdfWriterTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2021 Andreas Textor + * Copyright 2024 Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/scripts/do-release.sh b/scripts/do-release.sh index 09a0407f..6278c106 100755 --- a/scripts/do-release.sh +++ b/scripts/do-release.sh @@ -1,13 +1,13 @@ #!/bin/bash # -# Copyright 2021 Andreas Textor +# Copyright 2024 Andreas Textor # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, From a097f90904279ff8f93cb7d1dc8c5a0a7d930e07 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 23:45:24 +0100 Subject: [PATCH 159/280] Consolidate string template implementations --- .../buildtime/StringTemplate.java | 35 ------------------- .../buildtime/WriteVersionClass.java | 4 ++- .../atextor/ret/core/util/StringTemplate.java | 6 ++-- ret-diagram-owl/pom.xml | 6 ++++ .../ret/diagram/owl/GraphvizDocument.java | 3 +- .../ret/diagram/owl/GraphvizGenerator.java | 7 ++-- 6 files changed, 18 insertions(+), 43 deletions(-) delete mode 100644 ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java rename ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java => ret-core/src/main/java/de/atextor/ret/core/util/StringTemplate.java (89%) diff --git a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java deleted file mode 100644 index 77dde8c2..00000000 --- a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/StringTemplate.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2024 Andreas Textor - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package de.atextor.ret.core.buildtime; - -import java.util.Map; - -public class StringTemplate { - private final String template; - - public StringTemplate( final String template ) { - this.template = template; - } - - public String render( final Map values ) { - String result = template; - for ( final Map.Entry entry : values.entrySet() ) { - result = result.replace( "${" + entry.getKey() + "}", entry.getValue().toString() ); - } - return result; - } -} diff --git a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java index 85518c4d..2d34d4c3 100644 --- a/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java +++ b/ret-core/src-buildtime/main/java/de.atextor.ret.core/buildtime/WriteVersionClass.java @@ -16,6 +16,8 @@ package de.atextor.ret.core.buildtime; +import de.atextor.ret.core.util.StringTemplate; + import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; @@ -94,7 +96,7 @@ public static void main( final String[] args ) { gitBuildVersion, gitProperties.getProperty( "git.commit.id" ).substring( 0, 7 ) ) : gitBuildVersion; final String buildDate = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ); - final String content = VERSION_CLASS_TEMPLATE.render( Map.of( + final String content = VERSION_CLASS_TEMPLATE.apply( Map.of( "year", new SimpleDateFormat( "yyyy" ).format( new Date() ), // For now. May read this from contributors file in the future. "copyrightHolder", "Andreas Textor", diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java b/ret-core/src/main/java/de/atextor/ret/core/util/StringTemplate.java similarity index 89% rename from ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java rename to ret-core/src/main/java/de/atextor/ret/core/util/StringTemplate.java index 8ae651c1..cbdf73f4 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/Template.java +++ b/ret-core/src/main/java/de/atextor/ret/core/util/StringTemplate.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package de.atextor.ret.diagram.owl; +package de.atextor.ret.core.util; import java.util.Map; import java.util.function.Function; @@ -23,10 +23,10 @@ * Minimalistic String template. The template string can contain references to (e.g. ${foo}) that are replaced * with values on calling {@link #apply(Map)}. */ -public class Template implements Function, String> { +public class StringTemplate implements Function, String> { final private String template; - public Template( final String template ) { + public StringTemplate( final String template ) { this.template = template; } diff --git a/ret-diagram-owl/pom.xml b/ret-diagram-owl/pom.xml index 24a71686..57b0dcc6 100644 --- a/ret-diagram-owl/pom.xml +++ b/ret-diagram-owl/pom.xml @@ -34,6 +34,12 @@ + + + de.atextor.ret + ret-core + + com.github.ben-manes.caffeine diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java index e72742cd..91497b57 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizDocument.java @@ -17,6 +17,7 @@ package de.atextor.ret.diagram.owl; import com.google.common.collect.ImmutableMap; +import de.atextor.ret.core.util.StringTemplate; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -40,7 +41,7 @@ public class GraphvizDocument implements Function { public static final Configuration DEFAULT_CONFIGURATION = Configuration.builder().build(); - private static final Template GRAPHVIZ_TEMPLATE = new Template( """ + private static final StringTemplate GRAPHVIZ_TEMPLATE = new StringTemplate( """ digraph G { rankdir = ${rankdir} diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java index eeaf16dc..75ed92cd 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/GraphvizGenerator.java @@ -18,6 +18,7 @@ import de.atextor.ret.diagram.owl.graph.node.Class; import com.google.common.collect.Ordering; +import de.atextor.ret.core.util.StringTemplate; import de.atextor.ret.diagram.owl.graph.Edge; import de.atextor.ret.diagram.owl.graph.GraphElement; import de.atextor.ret.diagram.owl.graph.GraphVisitor; @@ -198,13 +199,13 @@ String getNodeValue( final String elementName, final Configuration configuration } } - final Template literalNodeTemplate = new Template( """ + final StringTemplate literalNodeTemplate = new StringTemplate( """ ${nodeId} [label="${value}"] """ ); - final Template htmlLabelNodeTemplate = new Template( """ + final StringTemplate htmlLabelNodeTemplate = new StringTemplate( """ ${nodeId} [label=<${value}>] """ ); - final Template invisibleNodeTemplate = new Template( """ + final StringTemplate invisibleNodeTemplate = new StringTemplate( """ ${nodeId} [label="", width="0", style="invis"] """ ); final Configuration configuration; From c540ff8a077e5df9fb11e90670282a7a607c46be Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 5 Jan 2024 23:50:01 +0100 Subject: [PATCH 160/280] Address code smells and typos --- .../de/atextor/ret/cli/AbstractCommand.java | 6 +-- .../java/de/atextor/ret/cli/ErrorMessage.java | 3 ++ .../java/de/atextor/ret/cli/LoggingMixin.java | 2 + .../src/main/java/de/atextor/ret/cli/Ret.java | 1 + .../java/de/atextor/ret/cli/RetDiagram.java | 26 +++++----- .../java/de/atextor/ret/cli/RetInfer.java | 1 + .../java/de/atextor/ret/cli/RetWrite.java | 51 ++++++++++--------- ...module_SubsystemRegistryServiceLoader.java | 2 +- ..._org_apache_jena_util_FileManagerImpl.java | 3 ++ .../ret/diagram/owl/DiagramGenerator.java | 4 +- .../atextor/ret/diagram/owl/FontEmbedder.java | 3 ++ .../ret/diagram/owl/GraphvizDocument.java | 2 + .../ret/diagram/owl/GraphvizGenerator.java | 10 +++- .../owl/graph/transformer/PunningRemover.java | 2 +- .../mappers/DefaultMappingConfiguration.java | 3 +- .../owl/mappers/DefaultNameMapper.java | 7 --- .../diagram/owl/mappers/OWLAxiomMapper.java | 2 +- .../diagram/owl/mappers/OWLObjectMapper.java | 16 +++--- .../diagram/owl/mappers/SWRLObjectMapper.java | 6 ++- .../printers/OWLClassExpressionPrinter.java | 2 +- ret-write/pom.xml | 6 +++ 21 files changed, 94 insertions(+), 64 deletions(-) diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java index 10c1ae93..829b33a7 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/AbstractCommand.java @@ -50,7 +50,7 @@ protected void commandFailed() { } protected Try openOutput( final @Nonnull String input, final String output, - final String targetFileExtension ) { + final String targetFileExtension ) { if ( output != null ) { // Output is given as - --> write to stdout if ( output.equals( "-" ) ) { @@ -116,7 +116,7 @@ protected OWLOntologyManager createOWLOntologyManager() { .add( new OWLOntologyFactoryImpl( new NonConcurrentOWLOntologyBuilder() ) ) .build(); - final Set storerFactories = + @SuppressWarnings( "SpellCheckingInspection" ) final Set storerFactories = ImmutableSet.builder() .add( new org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory() ) .add( new org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory() ) @@ -160,7 +160,7 @@ public Try loadOntology( final InputStream inputStream ) { } protected void exitWithErrorMessage( final Logger logger, final LoggingMixin loggingMixin, - final Throwable throwable ) { + final Throwable throwable ) { if ( loggingMixin.getVerbosity().length == 0 ) { System.err.println( "Error: " + throwable.getMessage() ); } else if ( loggingMixin.getVerbosity().length == 1 ) { diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java b/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java index 9b6356c2..fe67906d 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/ErrorMessage.java @@ -16,7 +16,10 @@ package de.atextor.ret.cli; +import java.io.Serial; + public class ErrorMessage extends Exception { + @Serial private static final long serialVersionUID = 5086560337386407192L; public ErrorMessage( final String message ) { diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java index c8e3f393..c97ce6ad 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/LoggingMixin.java @@ -29,6 +29,7 @@ import static picocli.CommandLine.Spec.Target.MIXEE; public class LoggingMixin { + @SuppressWarnings( { "unused", "SpellCheckingInspection" } ) private @CommandLine.Spec( MIXEE ) CommandLine.Model.CommandSpec mixee; @@ -43,6 +44,7 @@ public static int executionStrategy( final CommandLine.ParseResult parseResult ) return new CommandLine.RunLast().execute( parseResult ); } + @SuppressWarnings( "unused" ) @CommandLine.Option( names = { "-v", "--verbose" }, description = { "Specify multiple -v options to increase verbosity,", "e.g. use `-v`, `-vv` or `-vvv` for more details" } ) diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java b/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java index 5296cc45..b7e5619e 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/Ret.java @@ -68,6 +68,7 @@ private static void printError( final CommandLine commandLine, final Exception e private final CommandLine commandLine = new CommandLine( this ); + @SuppressWarnings( "unused" ) @CommandLine.Mixin LoggingMixin loggingMixin; diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java index 9f01e457..0d129543 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetDiagram.java @@ -28,6 +28,7 @@ import static de.atextor.ret.cli.RetDiagram.COMMAND_NAME; +@SuppressWarnings( "SpellCheckingInspection" ) @CommandLine.Command( name = COMMAND_NAME, description = "Generate automatically-layouted diagrams for an ontology", descriptionHeading = "%n@|bold Description|@:%n%n", @@ -43,56 +44,57 @@ public class RetDiagram extends AbstractCommand implements Runnable { private static final Configuration config = GraphvizDocument.DEFAULT_CONFIGURATION; + @SuppressWarnings( "unused" ) @CommandLine.Mixin LoggingMixin loggingMixin; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--fontname" }, description = "The font to use (Default: ${DEFAULT-VALUE})" ) private String fontname = config.fontname; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--fontsize" }, description = "Default font size (Default: ${DEFAULT-VALUE})" ) private int fontsize = config.fontsize; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--nodefontname" }, description = "Font for nodes (Default: ${DEFAULT-VALUE})" ) private String nodeFontName = config.nodeFontname; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--nodefontsize" }, description = "Font size for nodes (Default: ${DEFAULT-VALUE})" ) private int nodeFontsize = config.nodeFontsize; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--nodeshape" }, description = "Node shape (Default: ${DEFAULT-VALUE})" ) private String nodeShape = config.nodeShape; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--nodemargin" }, description = "Node margin (Default: ${DEFAULT-VALUE})" ) private String nodeMargin = config.nodeMargin; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--nodestyle" }, description = "Node style (Default: ${DEFAULT-VALUE})" ) private String nodeStyle = config.nodeStyle; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--format" }, description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format format = config.format; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--direction" }, description = "Diagram layout direction, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.LayoutDirection layoutDirection = config.layoutDirection; - @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal" } ) + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--dotbinary" }, description = "Path to dot binary (Default: ${DEFAULT-VALUE})" ) private String dotBinary = config.dotBinary; - @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal" } ) + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--fgcolor" }, description = "Foreground color (Default: ${DEFAULT-VALUE})" ) private String fgColor = config.fgColor; - @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal" } ) + @SuppressWarnings( { "SpellCheckingInspection", "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--bgcolor" }, description = "Background color (Default: ${DEFAULT-VALUE})" ) private String bgColor = config.bgColor; diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java index ae2868cc..b9fd371c 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetInfer.java @@ -44,6 +44,7 @@ public class RetInfer extends AbstractCommand implements Runnable { @SuppressWarnings( "unused" ) private static final Configuration config = Inferrer.DEFAULT_CONFIGURATION; + @SuppressWarnings( "unused" ) @CommandLine.Mixin LoggingMixin loggingMixin; diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java b/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java index 45593db2..e74a039e 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/RetWrite.java @@ -59,132 +59,133 @@ public class RetWrite extends AbstractCommand implements Runnable { private final String fallbackUri = "urn:owl-cli:empty"; + @SuppressWarnings( "unused" ) @CommandLine.Mixin LoggingMixin loggingMixin; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "-o", "--output" }, description = "Output file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format outputFormat = config.outputFormat; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "-i", "--input" }, description = "Input file format, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private Configuration.Format inputFormat = config.inputFormat; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "-p", "--prefix" }, description = "Prefix to add as @prefix when used.", mapFallbackValue = fallbackUri ) private Map prefixMap = new HashMap<>(); - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--prefixAlign" }, description = "Alignment of @prefix statements, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Alignment alignPrefixes = FormattingStyle.DEFAULT.alignPrefixes; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--encoding" }, description = "Output encoding, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.Charset encoding = FormattingStyle.DEFAULT.charset; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--doubleFormat" }, description = "Defines how double numbers are formatted (Default: ${DEFAULT-VALUE})" ) private String doubleFormatPattern = ( (DecimalFormat) FormattingStyle.DEFAULT.doubleFormat ).toPattern(); - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--endOfLine" }, description = "End of line style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.EndOfLineStyle endOfLineStyle = FormattingStyle.DEFAULT.endOfLine; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--indent" }, description = "Indent style, one of ${COMPLETION-CANDIDATES} (Default: ${DEFAULT-VALUE})" ) private FormattingStyle.IndentStyle indentStyle = FormattingStyle.DEFAULT.indentStyle; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--firstPredicateInNewLine" }, description = "Write first predicate in new line of block (Default: ${DEFAULT-VALUE})" ) private boolean firstPredicateInNewLine = FormattingStyle.DEFAULT.firstPredicateInNewLine; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--writeRdfType" }, description = "Write 'rdf:type' instead of 'a' (Default: ${DEFAULT-VALUE})" ) private boolean writeRdfType = !FormattingStyle.DEFAULT.useAForRdfType; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--useCommaByDefault" }, description = "Use commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private boolean useCommaByDefault = FormattingStyle.DEFAULT.useCommaByDefault; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--commaForPredicate" }, description = "A set of predicates that, when used multiple times, are separated by commas, even when " + "useCommaByDefault is false (Default: ${DEFAULT-VALUE})" ) private Set commaForPredicate = FormattingStyle.DEFAULT.commaForPredicate; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--noCommaForPredicate" }, description = "Use no commas for multiple objects (Default: ${DEFAULT-VALUE})" ) private Set noCommaForPredicate = FormattingStyle.DEFAULT.noCommaForPredicate; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--useLongLiterals" }, description = "Use long form for literals where possible (Default: ${DEFAULT-VALUE})" ) private boolean useLongLiterals = !FormattingStyle.DEFAULT.useShortLiterals; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--alignObjects" }, description = "Align objects for same predicates (Default: ${DEFAULT-VALUE})" ) private boolean alignObjects = FormattingStyle.DEFAULT.alignObjects; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--alignPredicates" }, description = "Align predicates for same subjects (Default: ${DEFAULT-VALUE})" ) private boolean alignPredicates = FormattingStyle.DEFAULT.alignPredicates; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--continuationIndentSize" }, description = "Indentation size after forced line wraps (Default: ${DEFAULT-VALUE})" ) private int continuationIndentSize = FormattingStyle.DEFAULT.continuationIndentSize; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--doNotInsertFinalNewline" }, description = "Do not insert newline at end of file (Default: ${DEFAULT-VALUE})" ) private boolean doNotInsertFinalNewline = !FormattingStyle.DEFAULT.insertFinalNewline; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--indentSize" }, description = "Indentation size in spaces (Default: ${DEFAULT-VALUE})" ) private int indentSize = FormattingStyle.DEFAULT.indentSize; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--keepUnusedPrefixes" }, description = "Keeps prefixes that are not part of any statement (Default: ${DEFAULT-VALUE})" ) private boolean keepUnusedPrefixes = FormattingStyle.DEFAULT.keepUnusedPrefixes; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--prefixOrder" }, description = "Sort order for prefixes (Default: ${DEFAULT-VALUE})" ) private List prefixOrder = FormattingStyle.DEFAULT.prefixOrder; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--subjectOrder" }, description = "Sort order for subjects by type (Default: ${DEFAULT-VALUE})" ) private List subjectOrder = FormattingStyle.DEFAULT.subjectOrder; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--predicateOrder" }, description = "Sort order for predicates (Default: ${DEFAULT-VALUE})" ) private List predicateOrder = FormattingStyle.DEFAULT.predicateOrder; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--objectOrder" }, description = "Sort order for objects (Default: ${DEFAULT-VALUE})" ) private List objectOrder = FormattingStyle.DEFAULT.objectOrder; - @SuppressWarnings( "FieldMayBeFinal" ) + @SuppressWarnings( { "FieldMayBeFinal", "CanBeFinal" } ) @CommandLine.Option( names = { "--anonymousNodeIdPattern" }, description = "Name pattern for blank node IDs (Default: ${DEFAULT-VALUE})" ) private String anonymousNodeIdPattern = diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java index b39d3b3d..28b88225 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader.java @@ -29,8 +29,8 @@ import java.util.List; -@TargetClass( SubsystemRegistryServiceLoader.class ) @SuppressWarnings( "unused" ) +@TargetClass( SubsystemRegistryServiceLoader.class ) public final class Target_org_apache_jena_base_module_SubsystemRegistryServiceLoader implements SubsystemRegistry { @Override @Substitute diff --git a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java index cdab0f3f..e42b5d50 100644 --- a/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java +++ b/ret-cli/src/main/java/de/atextor/ret/cli/substitution/Target_org_apache_jena_util_FileManagerImpl.java @@ -24,11 +24,14 @@ import java.util.List; +@SuppressWarnings( "unused" ) @TargetClass( FileManagerImpl.class ) public final class Target_org_apache_jena_util_FileManagerImpl { + @SuppressWarnings( { "unused", "ProtectedMemberInFinalClass" } ) @Alias protected List fmHandlers; + @SuppressWarnings( "unused" ) @Substitute public void addLocator( final Locator loc ) { fmHandlers.add( loc ); diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java index 163ef647..f6088104 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/DiagramGenerator.java @@ -137,9 +137,9 @@ private Try postProcess( final String dotOutput ) { public Try generate( final OWLOntology ontology, final OutputStream output, final Configuration configuration ) { LOG.info( "Applying ontology mappers" ); - final Stream ontologyGraphRepresenation = ontologyMapper.apply( ontology ).stream(); + final Stream ontologyGraphRepresentation = ontologyMapper.apply( ontology ).stream(); LOG.info( "Generating Graphviz document" ); - final GraphvizDocument graphvizDocument = graphvizGenerator.apply( ontologyGraphRepresenation ); + final GraphvizDocument graphvizDocument = graphvizGenerator.apply( ontologyGraphRepresentation ); final String graphvizGraph = graphvizDocument.apply( configuration ); LOG.trace( "Generated Graphviz document: {}", graphvizGraph ); diff --git a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java index 54bc5381..07c8203f 100644 --- a/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java +++ b/ret-diagram-owl/src/main/java/de/atextor/ret/diagram/owl/FontEmbedder.java @@ -24,6 +24,7 @@ * SVG post processor that embeds the 'owlcli' font used for the element type and disjoint union symbols * as a data URI. This is to make sure that the symbols are rendered the same in all browsers. */ +@SuppressWarnings( "SpellCheckingInspection" ) public class FontEmbedder implements Function, Try> { /* * This is the encoded symbol font that contains exactly the glyphs used in the diagrams. @@ -34,8 +35,10 @@ public class FontEmbedder implements Function, Try> { * 3. Adjust the glyphs using fontforge, File->Generate Fonts... save as .woff * 4. cat owlcli.woff | base64 -w 0 */ + // @formatter:off private final static String FONT = "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"; + // @formatter:on private final static String CSS_BLOCK = ""; + private final static String CSS_BLOCK = ""; @Override public Try apply( final Try svgDocument ) { diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizDocument.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizDocument.java index b79e3566..3ef601fc 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizDocument.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizDocument.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,8 +114,7 @@ GraphvizDocument merge( final GraphvizDocument other ) { @Override public String apply( final Configuration configuration ) { final Map templateMap = new ImmutableMap.Builder() - .put( "rankdir", configuration.layoutDirection == Configuration.LayoutDirection.TOP_TO_BOTTOM ? "TB" : - "LR" ) + .put( "rankdir", configuration.layoutDirection == Configuration.LayoutDirection.TOP_TO_BOTTOM ? "TB" : "LR" ) .put( "fontname", configuration.fontname ) .put( "fontsize", configuration.fontsize ) .put( "nodeFontname", configuration.nodeFontname ) diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizGenerator.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizGenerator.java index a24bfafe..875ca9e4 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizGenerator.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/GraphvizGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,12 +88,11 @@ public class GraphvizGenerator implements Function, Graphvi final Function decoratedEdgeToGraphviz = edge -> { final String label = edge.getLabel().getLabel(); - final String edgeStyle = - edgeTypeToGraphviz( edge.getType() ) - .map( style -> String.format( "%s, fontsize=%d, fontname=\"%s\", color=\"%s\", fontcolor=\"%s\"", - style, configuration.fontsize, configuration.fontname, configuration.fgColor, - configuration.fgColor ) ) - .orElse( "" ); + final String edgeStyle = edgeTypeToGraphviz( edge.getType() ) + .map( style -> String.format( "%s, fontsize=%d, fontname=\"%s\", color=\"%s\", fontcolor=\"%s\"", + style, configuration.fontsize, configuration.fontname, configuration.fgColor, + configuration.fgColor ) ) + .orElse( "" ); return GraphvizDocument.withEdge( new GraphvizDocument.Statement( String.format( "%s -> %s [label=\"%s\", %s]", escapeNodeId( edge.getFrom().getId() ), escapeNodeId( edge.getTo().getId() ), label, edgeStyle ) ) ); @@ -181,8 +180,8 @@ private enum Symbol { } /** - * Returns a DOT fragment for an element with this symbol. Note that the referenced font 'owlcli' - * is injected during rendering using the {@link FontEmbedder}. + * Returns a DOT fragment for an element with this symbol. Note that the referenced font 'owlcli' is + * injected during rendering using the {@link FontEmbedder}. * * @param elementName the name of the element * @param configuration the diagram generation configuration @@ -191,7 +190,7 @@ private enum Symbol { @SuppressWarnings( "SpellCheckingInspection" ) String getNodeValue( final String elementName, final Configuration configuration ) { return String.format( "%s " + - "%s", + "%s", symbolSize, color, symbol, configuration.fontsize, configuration.fgColor, configuration.fontname, elementName ); } diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/ThrowingConsumer.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/ThrowingConsumer.java index 79ee80b9..99609f3d 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/ThrowingConsumer.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/ThrowingConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Edge.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Edge.java index 9cd7daac..24f18b72 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Edge.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Edge.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Graph.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Graph.java index a7b7f909..b923991c 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Graph.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Graph.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,8 @@ public static Graph of( final Node node ) { } /** - * Builds a new graph by merging this graph with the other graph. This graph's focus node becomes the constructed graph's focus node. + * Builds a new graph by merging this graph with the other graph. This graph's focus node becomes the constructed + * graph's focus node. * * @param other the other graph * @return the new graph diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphElement.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphElement.java index 46fe0b7b..9ab03301 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphElement.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -94,7 +94,8 @@ default T as( final Class class_ ) { } /** - * Returns a view to this graph element: A stream containing this object cast to the given subclass if possible, empty stream otherwise + * Returns a view to this graph element: A stream containing this object cast to the given subclass if possible, + * empty stream otherwise * * @param class_ the subclass * @param the type of the subclass diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphVisitor.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphVisitor.java index 391648fc..ce28cbcf 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphVisitor.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/GraphVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Node.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Node.java index 78e65454..6af16378 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Node.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/Node.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -356,8 +356,8 @@ public interface Visitor { } /** - * ID of a node that has the (unique) internal identifier string, and if present, the {@link IRI} of the - * ontology element that is represented by the node having this ID. + * ID of a node that has the (unique) internal identifier string, and if present, the {@link IRI} of the ontology + * element that is represented by the node having this ID. */ @Getter @EqualsAndHashCode diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/AnnotationProperty.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/AnnotationProperty.java index ea05d29c..0302737f 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/AnnotationProperty.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/AnnotationProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Class.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Class.java index ae65e17b..1a0e5999 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Class.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Class.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ClosedClass.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ClosedClass.java index 1faa4600..36444240 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ClosedClass.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ClosedClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Complement.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Complement.java index 8be45251..df53a86e 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Complement.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Complement.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataExactCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataExactCardinality.java index 77eaac44..e1f0efd0 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataExactCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataExactCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMaximalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMaximalCardinality.java index 90887ad4..e123ce2f 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMaximalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMaximalCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMinimalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMinimalCardinality.java index 62544368..b5dc5d60 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMinimalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataMinimalCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataProperty.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataProperty.java index bdcaa4c3..46e15fc4 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataProperty.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DataProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Datatype.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Datatype.java index 02d49237..0991c4e1 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Datatype.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Datatype.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DisjointUnion.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DisjointUnion.java index 289ed573..fe6505b1 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DisjointUnion.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/DisjointUnion.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Disjointness.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Disjointness.java index edb719db..a0c741cf 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Disjointness.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Disjointness.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Equality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Equality.java index 3ae76bbc..1285a3d4 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Equality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Equality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ExistentialRestriction.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ExistentialRestriction.java index 00965565..de318255 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ExistentialRestriction.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ExistentialRestriction.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/IRIReference.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/IRIReference.java index 2679e00a..ac9f2dfe 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/IRIReference.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/IRIReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,10 +24,9 @@ import org.semanticweb.owlapi.model.IRI; /** - * Represents a reference to some yet unknown other graph that has a {@link Node.Id} with a given {@link IRI}. - * This type of node should never end up in the final graph, as it is resolved by the - * {@link IriReferenceResolver} after the Axiom -> Graph Elements mapping - * is done. + * Represents a reference to some yet unknown other graph that has a {@link Node.Id} with a given {@link IRI}. This type + * of node should never end up in the final graph, as it is resolved by the {@link IriReferenceResolver} after the Axiom + * -> Graph Elements mapping is done. */ @Value @EqualsAndHashCode( callSuper = true ) diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Individual.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Individual.java index 593b2244..7efde5f4 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Individual.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Individual.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inequality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inequality.java index c20b0174..1541a331 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inequality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inequality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Intersection.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Intersection.java index 0a82e879..483e95fa 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Intersection.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Intersection.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inverse.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inverse.java index c874d43b..c738beaf 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inverse.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Inverse.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Invisible.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Invisible.java index f6773e2b..7930c1a4 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Invisible.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Invisible.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Key.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Key.java index a00471ef..144fcd2e 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Key.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Key.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Literal.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Literal.java index c3213a4f..30ab010b 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Literal.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Literal.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectExactCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectExactCardinality.java index 946c524f..813d0609 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectExactCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectExactCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMaximalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMaximalCardinality.java index 519ec065..41b4b036 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMaximalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMaximalCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMinimalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMinimalCardinality.java index a8a66277..40eb0ef7 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMinimalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectMinimalCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectProperty.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectProperty.java index 465609a6..2e518d47 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectProperty.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java index 57c31d8e..5f181352 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedExactCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java index f8365cd7..98c5d1aa 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMaximalCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java index 1c4d6897..70b3ee6b 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ObjectQualifiedMinimalCardinality.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyChain.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyChain.java index 8b0916fb..b2be1b17 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyChain.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyChain.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyMarker.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyMarker.java index c07f91f9..c03dafe4 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyMarker.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/PropertyMarker.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,8 @@ import java.util.Set; /** - * Represents a property marker node in the graph, i.e. a node that contains the list of attributes that a given - * OWL Object Property or OWL Data Property has. + * Represents a property marker node in the graph, i.e. a node that contains the list of attributes that a given OWL + * Object Property or OWL Data Property has. */ @Value @EqualsAndHashCode( callSuper = true ) diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Rule.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Rule.java index 05dedce5..bc554344 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Rule.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Rule.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Self.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Self.java index f51da0e6..86d834ac 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Self.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Self.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Union.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Union.java index bb09412a..b5be451f 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Union.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/Union.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/UniversalRestriction.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/UniversalRestriction.java index 266113ea..781e1b02 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/UniversalRestriction.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/UniversalRestriction.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ValueRestriction.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ValueRestriction.java index 07240dc0..ac922c44 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ValueRestriction.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/node/ValueRestriction.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/ChangeSet.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/ChangeSet.java index 8352a7ab..68e7182e 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/ChangeSet.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/ChangeSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/GraphTransformer.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/GraphTransformer.java index b84e2b30..abd1f9a9 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/GraphTransformer.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/GraphTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,8 +46,8 @@ protected Stream findNodesWithIri( final Set graph, final IR } /** - * Calculates a {@link ChangeSet} for a given graph in which all edges pointing to a given node are instead now pointing to a diffent - * node + * Calculates a {@link ChangeSet} for a given graph in which all edges pointing to a given node are instead now + * pointing to a diffent node * * @param graph the graph * @param oldToNode the old node @@ -59,8 +59,8 @@ protected ChangeSet updateEdgesTo( final Set graph, final Node old } /** - * Calculates a {@link ChangeSet} for a given graph in which all edges outgoing from a given node are instead now outgoing from a - * different node + * Calculates a {@link ChangeSet} for a given graph in which all edges outgoing from a given node are instead now + * outgoing from a different node * * @param graph the graph * @param oldFromNode the old node diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/IriReferenceResolver.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/IriReferenceResolver.java index 56f96a39..24c9464c 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/IriReferenceResolver.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/IriReferenceResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,9 @@ import java.util.stream.Stream; /** - * Implements a graph transformation that removes all nodes of type {@link IRIReference} from a graph and - * replaces them with the corresponding direct links to the referenced nodes where possible, and with literal - * nodes representing the reference IRI otherwise + * Implements a graph transformation that removes all nodes of type {@link IRIReference} from a graph and replaces them + * with the corresponding direct links to the referenced nodes where possible, and with literal nodes representing the + * reference IRI otherwise */ public class IriReferenceResolver extends GraphTransformer { private final MappingConfiguration mappingConfiguration; diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PropertyMarkerMerger.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PropertyMarkerMerger.java index b18a21df..2ce5e41f 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PropertyMarkerMerger.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PropertyMarkerMerger.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,8 +31,8 @@ import java.util.stream.Stream; /** - * Implements a graph transformer that merges multiple {@link PropertyMarker}s on a given Object property - * or Data Property into one Property Marker + * Implements a graph transformer that merges multiple {@link PropertyMarker}s on a given Object property or Data + * Property into one Property Marker */ public class PropertyMarkerMerger extends GraphTransformer { private final MappingConfiguration mappingConfiguration; @@ -63,10 +63,9 @@ private Optional markerByEdge( final Set graph, fi } private ChangeSet mergePropertyMarkers( final Set> propertyMarkers ) { - final Set mergedKindSet = - propertyMarkers.stream().flatMap( marker -> marker._2().getKind().stream() ).collect( Collectors.toSet() ); - final PropertyMarker newMarker = - new PropertyMarker( mappingConfiguration.getIdentifierMapper().getSyntheticId(), mergedKindSet ); + final Set mergedKindSet = propertyMarkers.stream().flatMap( marker -> marker._2().getKind().stream() ).collect( + Collectors.toSet() ); + final PropertyMarker newMarker = new PropertyMarker( mappingConfiguration.getIdentifierMapper().getSyntheticId(), mergedKindSet ); final Edge newEdge = propertyMarkers.iterator().next()._1().setTo( newMarker ); diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PunningRemover.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PunningRemover.java index 0eb63bcb..8c459365 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PunningRemover.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/graph/transformer/PunningRemover.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,9 @@ /** * Implements a graph transformer that resolves - * Punning in a graph: An input ontology that - * uses punning for e.g. an individual and a class results in a graph that contains both the individual and the class - * as nodes, but both share the same {@link Node.Id}, as it is derived from the element's + * Punning in a graph: An input ontology that uses + * punning for e.g. an individual and a class results in a graph that contains both the individual and the class as + * nodes, but both share the same {@link Node.Id}, as it is derived from the element's * {@link org.semanticweb.owlapi.model.IRI}. This transformer replaces the nodes with new, uniquely identified nodes * (that keep the original IRI in their IDs) and updates all edges in the graph accordingly. */ @@ -58,7 +58,8 @@ public PunningRemover( final MappingConfiguration mappingConfiguration ) { @Override public Set apply( final Set graph ) { LOG.debug( "Removing punning in {}", graph ); - @SuppressWarnings( "OptionalGetWithoutIsPresent" ) final Set result = graph.stream() + @SuppressWarnings( "OptionalGetWithoutIsPresent" ) + final Set result = graph.stream() .filter( GraphElement::isNode ) .map( GraphElement::asNode ) .filter( node -> node.getId().getIri().isPresent() ) @@ -81,8 +82,7 @@ private Stream updateNode( final Set graph, final Node } private Node.Id buildNewNodeId( final Node.Id original ) { - return original.getIri().map( iri -> - mappingConfiguration.getIdentifierMapper().getSyntheticIdForIri( iri ) ) + return original.getIri().map( iri -> mappingConfiguration.getIdentifierMapper().getSyntheticIdForIri( iri ) ) .orElseGet( () -> mappingConfiguration.getIdentifierMapper().getSyntheticId() ); } } diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultIdentifierMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultIdentifierMapper.java index cf63c20e..2af38443 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultIdentifierMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultIdentifierMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultMappingConfiguration.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultMappingConfiguration.java index 65865416..74a78a7f 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultMappingConfiguration.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultMappingConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultNameMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultNameMapper.java index 09b12e9d..ee4885a8 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultNameMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/DefaultNameMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/IdentifierMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/IdentifierMapper.java index da619f3b..d9f36797 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/IdentifierMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/IdentifierMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,8 @@ import org.semanticweb.owlapi.model.IRI; /** - * Creates {@link Node.Id}s for named nodes (i.e. for ontology elements that are identified by {@link IRI}s) - * or anonymous nodes + * Creates {@link Node.Id}s for named nodes (i.e. for ontology elements that are identified by {@link IRI}s) or + * anonymous nodes */ public interface IdentifierMapper { /** diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/MappingConfiguration.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/MappingConfiguration.java index 1a5cbc3f..b7f955ef 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/MappingConfiguration.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/MappingConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,8 @@ public interface MappingConfiguration { OWLAxiomVisitorEx getOwlAxiomMapper(); /** - * The OWL class expression mapper translates OWL class expressions (declarations, but also unions, intersections etc.) to graphs + * The OWL class expression mapper translates OWL class expressions (declarations, but also unions, intersections + * etc.) to graphs * * @return the mapper */ @@ -61,7 +62,8 @@ public interface MappingConfiguration { OWLPropertyExpressionVisitorEx getOwlPropertyExpressionMapper(); /** - * The OWL object mapper unifies the interfaces for various other mappers, and translates the corresponding OWL objects to graphs + * The OWL object mapper unifies the interfaces for various other mappers, and translates the corresponding OWL + * objects to graphs * * @return the mapper */ @@ -117,14 +119,16 @@ public interface MappingConfiguration { NameMapper getNameMapper(); /** - * The OWL data printer translates data axioms, such as data unions and complements, to expression String representations + * The OWL data printer translates data axioms, such as data unions and complements, to expression String + * representations * * @return the printer */ OWLDataVisitorEx getOwlDataPrinter(); /** - * The OWL property expression printer translates OWL object properties and data properties to expression String representations + * The OWL property expression printer translates OWL object properties and data properties to expression String + * representations * * @return the printer */ diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/NameMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/NameMapper.java index 2d86717e..5a7d2f2d 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/NameMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/NameMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAnnotationObjectMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAnnotationObjectMapper.java index 7c7ff212..a04a550b 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAnnotationObjectMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAnnotationObjectMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAxiomMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAxiomMapper.java index 5091c7f5..1a5a9a12 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAxiomMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLAxiomMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -130,8 +130,8 @@ public Graph visit( final @Nonnull OWLSubClassOfAxiom axiom ) { } private

Stream - propertyStructure( final OWLPropertyAssertionAxiom axiom, final Node thirdNode, - final Edge.Type subjectToThirdNodeType ) { + propertyStructure( final OWLPropertyAssertionAxiom axiom, final Node thirdNode, + final Edge.Type subjectToThirdNodeType ) { final Graph subjectGraph = axiom.getSubject().accept( mappingConfig.getOwlIndividualMapper() ); final Graph propertyGraph = axiom.getProperty().accept( mappingConfig.getOwlPropertyExpressionMapper() ); @@ -181,7 +181,8 @@ private

> G return domainGraph.and( propertyGraph ).and( domainEdge ); } - private

> Graph propertyRange( final A axiom ) { + private

> Graph propertyRange( + final A axiom ) { final Graph propertyGraph = axiom.getProperty().accept( mappingConfig.getOwlPropertyExpressionMapper() ); final Graph rangeGraph = axiom.getRange().accept( mappingConfig.getOwlObjectMapper() ); final Edge rangeEdge = new Edge.Decorated( Edge.Type.DEFAULT_ARROW, propertyGraph.getNode(), @@ -298,8 +299,8 @@ public Graph visit( final @Nonnull OWLFunctionalDataPropertyAxiom axiom ) { } /** - * Shared logic for axioms that generate sets of nodes that are pairwise equivalent, - * e.g. {@link org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom}s. + * Shared logic for axioms that generate sets of nodes that are pairwise equivalent, e.g. + * {@link org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom}s. * * @param axiom The axiom to generate results for * @param visitor The visitor that handles the type of axiom @@ -309,7 +310,7 @@ public Graph visit( final @Nonnull OWLFunctionalDataPropertyAxiom axiom ) { * @return the graph representing the equivalency */ private , V extends OWLObjectVisitorEx> - Graph pairwiseEquivalent( final A axiom, final V visitor ) { + Graph pairwiseEquivalent( final A axiom, final V visitor ) { final Map operands = axiom.operands().collect( Collectors.toMap( Function.identity(), object -> object.accept( visitor ) ) ); @@ -321,11 +322,10 @@ Graph pairwiseEquivalent( final A axiom, final V visitor ) { final List newList = new ArrayList<>( expressionsList ); newList.sort( Comparator.comparing( o -> operands.get( o ).getNode().getId().getId() ) ); return newList; - } - ).filter( expressionsList -> { - final Iterator iterator = expressionsList.iterator(); - return !iterator.next().equals( iterator.next() ); - } ).collect( Collectors.toSet() ); + } ).filter( expressionsList -> { + final Iterator iterator = expressionsList.iterator(); + return !iterator.next().equals( iterator.next() ); + } ).collect( Collectors.toSet() ); // For each of the combinations, create a corresponding edge final Stream edges = combinations.stream().map( expressionsList -> { @@ -349,8 +349,7 @@ public Graph visit( final @Nonnull OWLClassAssertionAxiom axiom ) { final OWLIndividual individual = axiom.getIndividual(); final OWLClassExpression classExpression = axiom.getClassExpression(); final Graph individualGraph = individual.accept( mappingConfig.getOwlIndividualMapper() ); - final Graph classExpressionGraph = - classExpression.accept( mappingConfig.getOwlClassExpressionMapper() ); + final Graph classExpressionGraph = classExpression.accept( mappingConfig.getOwlClassExpressionMapper() ); final Edge edge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, individualGraph.getNode(), classExpressionGraph.getNode() ); @@ -507,44 +506,42 @@ public Graph visit( final @Nonnull OWLAnnotationPropertyRangeAxiom axiom ) { @Override public Graph visit( final @Nonnull SWRLRule rule ) { - final Function, String> reduceWithConjunction = stream -> - stream.map( element -> element.as( Literal.class ) ) - .map( Literal::getValue ) - .collect( Collectors.joining( " " + Rule.CONJUNCTION_SYMBOL + " " ) ); + final Function, String> reduceWithConjunction = stream -> stream.map( element -> element.as( Literal.class ) ) + .map( Literal::getValue ) + .collect( Collectors.joining( " " + Rule.CONJUNCTION_SYMBOL + " " ) ); - final Map> partitionedBodyElements = - rule.body().flatMap( atom -> atom.accept( mappingConfig.getSwrlObjectMapper() ).toStream() ) - .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); + final Map> partitionedBodyElements = rule.body().flatMap( atom -> atom.accept( mappingConfig + .getSwrlObjectMapper() ).toStream() ) + .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); final String bodyExpression = reduceWithConjunction.apply( partitionedBodyElements.get( true ).stream() ); - final Map> partitionedHeadElements = - rule.head().flatMap( atom -> atom.accept( mappingConfig.getSwrlObjectMapper() ).toStream() ) - .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); + final Map> partitionedHeadElements = rule.head().flatMap( atom -> atom.accept( mappingConfig + .getSwrlObjectMapper() ).toStream() ) + .collect( Collectors.partitioningBy( SWRLObjectMapper.IS_RULE_SYNTAX_PART ) ); final String headExpression = reduceWithConjunction.apply( partitionedHeadElements.get( true ).stream() ); final Node ruleNode = new Rule( mappingConfig.getIdentifierMapper().getSyntheticId(), String.format( "%s %s %s", bodyExpression, Rule.IMPLICATION_SYMBOL, headExpression ) ); - final Set allSyntaxParts = - Stream.of( partitionedBodyElements.get( true ), partitionedHeadElements.get( true ) ) - .flatMap( List::stream ) - .map( GraphElement::asNode ) - .collect( Collectors.toSet() ); - - final Stream remainingElements = - Stream.of( partitionedBodyElements.get( false ), partitionedHeadElements.get( false ) ) - .flatMap( List::stream ) - .map( element -> { - if ( element.isEdge() ) { - final Edge edge = element.asEdge(); - if ( allSyntaxParts.contains( edge.getFrom() ) ) { - return edge.setFrom( ruleNode ); - } + final Set allSyntaxParts = Stream.of( partitionedBodyElements.get( true ), partitionedHeadElements.get( true ) ) + .flatMap( List::stream ) + .map( GraphElement::asNode ) + .collect( Collectors.toSet() ); + + final Stream remainingElements = Stream.of( partitionedBodyElements.get( false ), partitionedHeadElements.get( + false ) ) + .flatMap( List::stream ) + .map( element -> { + if ( element.isEdge() ) { + final Edge edge = element.asEdge(); + if ( allSyntaxParts.contains( edge.getFrom() ) ) { + return edge.setFrom( ruleNode ); } - return element; - } ); + } + return element; + } ); return Graph.of( ruleNode, remainingElements ); } diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLClassExpressionMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLClassExpressionMapper.java index 3c31cf82..4019ef87 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLClassExpressionMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLClassExpressionMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLDataMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLDataMapper.java index 510b74d9..c541ff3e 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLDataMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLDataMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,8 +66,7 @@ private Stream createEdgeToDataRange( final Node sourceNode, @Override public Graph visit( final @Nonnull OWLDataComplementOf dataRange ) { - final Node complementNode = - new Complement( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Node complementNode = new Complement( mappingConfig.getIdentifierMapper().getSyntheticId() ); final Stream remainingElements = createEdgeToDataRange( complementNode, dataRange.getDataRange() ); return Graph.of( complementNode, remainingElements ); @@ -75,8 +74,7 @@ public Graph visit( final @Nonnull OWLDataComplementOf dataRange ) { @Override public Graph visit( final @Nonnull OWLDataOneOf dataRange ) { - final Node restrictionNode = - new ClosedClass( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Node restrictionNode = new ClosedClass( mappingConfig.getIdentifierMapper().getSyntheticId() ); return dataRange.values().map( value -> { final Graph valueGraph = value.accept( mappingConfig.getOwlDataMapper() ); final Edge vEdge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, restrictionNode, valueGraph.getNode() ); @@ -86,18 +84,17 @@ public Graph visit( final @Nonnull OWLDataOneOf dataRange ) { @Override public Graph visit( final @Nonnull OWLDataIntersectionOf dataRange ) { - final Node intersectionNode = - new Intersection( mappingConfig.getIdentifierMapper().getSyntheticId() ); - final Stream remainingElements = dataRange.operands().flatMap( operand -> - createEdgeToDataRange( intersectionNode, operand ) ); + final Node intersectionNode = new Intersection( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Stream remainingElements = dataRange.operands().flatMap( operand -> createEdgeToDataRange( intersectionNode, + operand ) ); return Graph.of( intersectionNode, remainingElements ); } @Override public Graph visit( final @Nonnull OWLDataUnionOf dataRange ) { final Node unionNode = new Union( mappingConfig.getIdentifierMapper().getSyntheticId() ); - final Stream remainingElements = dataRange.operands().flatMap( operand -> - createEdgeToDataRange( unionNode, operand ) ); + final Stream remainingElements = dataRange.operands().flatMap( operand -> createEdgeToDataRange( unionNode, + operand ) ); return Graph.of( unionNode, remainingElements ); } diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLEntityMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLEntityMapper.java index ad839db7..e65b75f0 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLEntityMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLEntityMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLIndividualMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLIndividualMapper.java index 759b0d40..7d9a62e8 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLIndividualMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLIndividualMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLObjectMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLObjectMapper.java index 4e94d7bf..a2dc8fdb 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLObjectMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLObjectMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,8 +53,8 @@ import javax.annotation.Nonnull; /** - * Dispatcher of multiple types of OWL objects; this is called in some generic mapping operations. - * Maps {@link org.semanticweb.owlapi.model.OWLObject}s to {@link Graph}s. + * Dispatcher of multiple types of OWL objects; this is called in some generic mapping operations. Maps + * {@link org.semanticweb.owlapi.model.OWLObject}s to {@link Graph}s. */ public class OWLObjectMapper implements OWLObjectVisitorEx { private final MappingConfiguration mappingConfig; diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLOntologyMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLOntologyMapper.java index 06eae5db..e00b85b8 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLOntologyMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLOntologyMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,10 +30,10 @@ import java.util.stream.Collectors; /** - * Main class for mapping an {@link OWLOntology} to a {@link Graph}. The mapping is done in two steps: - * First, all axioms in the ontology are separately mapped using the respective OWL*Mappers into nodes and edges. - * Secondly, the {@link GraphTransformer}s clean up the graph by - * performing changes that take the context of the whole graph into account. + * Main class for mapping an {@link OWLOntology} to a {@link Graph}. The mapping is done in two steps: First, all axioms + * in the ontology are separately mapped using the respective OWL*Mappers into nodes and edges. Secondly, the + * {@link GraphTransformer}s clean up the graph by performing changes that take the context of the whole graph into + * account. */ public class OWLOntologyMapper implements Function> { private final MappingConfiguration mappingConfiguration; @@ -50,8 +50,7 @@ public OWLOntologyMapper( final MappingConfiguration mappingConfiguration ) { transformers = List.of( new PunningRemover( mappingConfiguration ), new IriReferenceResolver( mappingConfiguration ), - new PropertyMarkerMerger( mappingConfiguration ) - ); + new PropertyMarkerMerger( mappingConfiguration ) ); } @Override diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLPropertyExpressionMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLPropertyExpressionMapper.java index c4eb2d39..ce71d22e 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLPropertyExpressionMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/OWLPropertyExpressionMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,11 +49,9 @@ public OWLPropertyExpressionMapper( final MappingConfiguration mappingConfig ) { @Override public Graph visit( final @Nonnull OWLObjectInverseOf property ) { - final Node inverseNode = - new Inverse( mappingConfig.getIdentifierMapper().getSyntheticId() ); + final Node inverseNode = new Inverse( mappingConfig.getIdentifierMapper().getSyntheticId() ); final OWLPropertyExpression invertedProperty = property.getInverseProperty(); - final Graph propertyVisitorGraph = - invertedProperty.accept( mappingConfig.getOwlPropertyExpressionMapper() ); + final Graph propertyVisitorGraph = invertedProperty.accept( mappingConfig.getOwlPropertyExpressionMapper() ); final Edge propertyEdge = new Edge.Plain( Edge.Type.DEFAULT_ARROW, inverseNode, propertyVisitorGraph .getNode() ); return Graph.of( inverseNode ).and( propertyVisitorGraph ).and( propertyEdge ); diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/SWRLObjectMapper.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/SWRLObjectMapper.java index d13c43ec..a446b054 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/SWRLObjectMapper.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/mappers/SWRLObjectMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,9 +50,9 @@ import static io.vavr.API.TODO; /** - * A mapper that translates SWRL rules into a {@link Graph}: The rule is represented as one distinct node that contains a - * human-readable string representation of the rule, with outgoing edges to the nodes representing the elements (classes etc.) - * that are referred to in the rule. + * A mapper that translates SWRL rules into a {@link Graph}: The rule is represented as one distinct node that contains + * a human-readable string representation of the rule, with outgoing edges to the nodes representing the elements + * (classes etc.) that are referred to in the rule. */ public class SWRLObjectMapper implements SWRLObjectVisitorEx { /** @@ -61,16 +61,14 @@ public class SWRLObjectMapper implements SWRLObjectVisitorEx { private static final IRI LITERAL_ID = IRI.create( "urn:owl-cli:literal-id" ); /** - * During traversal of the rule expression tree, both Literal nodes and other GraphElements - * (mainly Edges) are collected. The values of the Literal nodes are concatenated in the end - * to render the final rule representation. In order to differentiate the to-be-concatenated - * Literal nodes from "regular" Literal nodes that might occur, they are given an internal - * identifier "marker" IRI. The concatenation is done in + * During traversal of the rule expression tree, both Literal nodes and other GraphElements (mainly Edges) are + * collected. The values of the Literal nodes are concatenated in the end to render the final rule representation. + * In order to differentiate the to-be-concatenated Literal nodes from "regular" Literal nodes that might occur, + * they are given an internal identifier "marker" IRI. The concatenation is done in * {@link OWLAxiomMapper#visit(SWRLRule)}. */ - public static final Predicate IS_RULE_SYNTAX_PART = - graphElement -> graphElement.is( Literal.class ) && - graphElement.as( Literal.class ).getId().getIri().map( iri -> iri.equals( LITERAL_ID ) ).orElse( false ); + public static final Predicate IS_RULE_SYNTAX_PART = graphElement -> graphElement.is( Literal.class ) && + graphElement.as( Literal.class ).getId().getIri().map( iri -> iri.equals( LITERAL_ID ) ).orElse( false ); private final MappingConfiguration mappingConfig; @@ -112,8 +110,7 @@ public Graph visit( final @Nonnull SWRLDataRangeAtom atom ) { } private List argumentElements( final SWRLAtom atom ) { - return atom.allArguments().flatMap( argument -> - argument.accept( this ).toStream() ).collect( Collectors.toList() ); + return atom.allArguments().flatMap( argument -> argument.accept( this ).toStream() ).collect( Collectors.toList() ); } private String printArgumentElements( final List argumentElements ) { @@ -136,8 +133,7 @@ private Graph visitPropertyAtom( final SWRLBinaryAtom argumentGraphElements = argumentElements( atom ); final String arguments = printArgumentElements( argumentGraphElements ); - final String builtin = Namespaces.SWRLB.inNamespace( atom.getPredicate() ) ? - String.format( "swrlb:%s", atom.getPredicate().getFragment() ) : - mappingConfig.getNameMapper().getName( atom.getPredicate() ); + final String builtin = Namespaces.SWRLB.inNamespace( atom.getPredicate() ) ? String.format( "swrlb:%s", atom.getPredicate() + .getFragment() ) : mappingConfig.getNameMapper().getName( atom.getPredicate() ); final String label = String.format( "%s(%s)", builtin, arguments ); return Graph.of( new Literal( mappingConfig.getIdentifierMapper().getSyntheticIdForIri( LITERAL_ID ), label ) ); diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLClassExpressionPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLClassExpressionPrinter.java index eedf3375..0b1c8f75 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLClassExpressionPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLClassExpressionPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,7 +100,7 @@ public String visit( final @Nonnull OWLObjectHasValue classExpression ) { } private > - String printQualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { + String printQualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { return String.format( "%s %s %d %s", classExpression.getProperty().accept( mappingConfig.getOwlPropertyExpressionPrinter() ), restrictionType, @@ -109,7 +109,7 @@ String printQualifiedCardinalityRestriction( final T classExpression, final Stri } private - String printUnqualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { + String printUnqualifiedCardinalityRestriction( final T classExpression, final String restrictionType ) { return String.format( "%s %s %d", classExpression.getProperty().accept( mappingConfig.getOwlPropertyExpressionPrinter() ), restrictionType, diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLDataPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLDataPrinter.java index 62fdaa1e..727c782d 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLDataPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLDataPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLIndividualPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLIndividualPrinter.java index 0645e02f..af130c34 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLIndividualPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLIndividualPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLPropertyExpressionPrinter.java b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLPropertyExpressionPrinter.java index 474e4360..9e11853f 100644 --- a/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLPropertyExpressionPrinter.java +++ b/cool-rdf-diagram-owl/src/main/java/cool/rdf/diagram/owl/printers/OWLPropertyExpressionPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FMT.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FMT.java index 29d5fa8c..1bf5d4f6 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FMT.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FMT.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FormattingStyle.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FormattingStyle.java index 7ba75b80..321c31ad 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FormattingStyle.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/FormattingStyle.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,8 +48,7 @@ public class FormattingStyle { Prefixes.RDFS, Prefixes.XSD, Prefixes.OWL, - Prefixes.DCTERMS - ); + Prefixes.DCTERMS ); @Builder.Default public String emptyRdfBase = TurtleFormatter.DEFAULT_EMPTY_BASE; @@ -103,7 +102,7 @@ public class FormattingStyle { public Charset charset = Charset.UTF_8; @Builder.Default - public NumberFormat doubleFormat = new DecimalFormat("0.####E0" , DecimalFormatSymbols.getInstance(Locale.US)); + public NumberFormat doubleFormat = new DecimalFormat( "0.####E0", DecimalFormatSymbols.getInstance( Locale.US ) ); @Builder.Default public boolean enableDoubleFormatting = false; @@ -173,8 +172,7 @@ public class FormattingStyle { "rdf", "rdfs", "xsd", - "owl" - ); + "owl" ); @Builder.Default public List subjectOrder = List.of( @@ -187,16 +185,14 @@ public class FormattingStyle { OWL2.AnnotationProperty, OWL2.NamedIndividual, OWL2.AllDifferent, - OWL2.Axiom - ); + OWL2.Axiom ); @Builder.Default public List predicateOrder = List.of( RDF.type, RDFS.label, RDFS.comment, - DCTerms.description - ); + DCTerms.description ); @Builder.Default public List objectOrder = List.of( @@ -210,8 +206,7 @@ public class FormattingStyle { OWL2.SymmetricProperty, OWL2.AsymmetricProperty, OWL2.ReflexiveProperty, - OWL2.IrreflexiveProperty - ); + OWL2.IrreflexiveProperty ); @Builder.Default public BiFunction anonymousNodeIdGenerator = ( resource, integer ) -> "gen" + integer; diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/RDFNodeComparatorFactory.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/RDFNodeComparatorFactory.java index d47ee209..bc9958b7 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/RDFNodeComparatorFactory.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/RDFNodeComparatorFactory.java @@ -1,3 +1,19 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package cool.rdf.formatter; import cool.rdf.formatter.blanknode.BlankNodeMetadata; @@ -14,13 +30,13 @@ public class RDFNodeComparatorFactory { private final BlankNodeMetadata blankNodeOrdering; private final RDFNodeComparator rdfNodeComparator = new RDFNodeComparator(); - public RDFNodeComparatorFactory(PrefixMapping prefixMapping, BlankNodeMetadata blankNodeOrdering) { + public RDFNodeComparatorFactory( PrefixMapping prefixMapping, BlankNodeMetadata blankNodeOrdering ) { this.prefixMapping = prefixMapping; this.blankNodeOrdering = blankNodeOrdering; } - public RDFNodeComparatorFactory(PrefixMapping prefixMapping) { - this(prefixMapping, null); + public RDFNodeComparatorFactory( PrefixMapping prefixMapping ) { + this( prefixMapping, null ); } public RDFNodeComparator comparator() { @@ -28,28 +44,30 @@ public RDFNodeComparator comparator() { } private class RDFNodeComparator implements Comparator { - @Override public int compare(RDFNode left, RDFNode right) { - if (left.isURIResource()){ - if (right.isURIResource()){ - return prefixMapping.shortForm(left.asResource().getURI()).compareTo(prefixMapping.shortForm(right.asResource().getURI())); - } else if (right.isAnon()) { - return -1 ; // uris first + @Override + public int compare( RDFNode left, RDFNode right ) { + if ( left.isURIResource() ) { + if ( right.isURIResource() ) { + return prefixMapping.shortForm( left.asResource().getURI() ).compareTo( prefixMapping.shortForm( right.asResource() + .getURI() ) ); + } else if ( right.isAnon() ) { + return -1; // uris first } - } else if (left.isAnon()) { - if (right.isAnon()) { - if (blankNodeOrdering != null) { - return Optional.ofNullable(blankNodeOrdering.getOrder(left.asResource().asNode())) - .orElse(Long.MAX_VALUE) - .compareTo(Optional.ofNullable( - blankNodeOrdering.getOrder(right.asResource().asNode())) - .orElse(Long.MAX_VALUE)); + } else if ( left.isAnon() ) { + if ( right.isAnon() ) { + if ( blankNodeOrdering != null ) { + return Optional.ofNullable( blankNodeOrdering.getOrder( left.asResource().asNode() ) ) + .orElse( Long.MAX_VALUE ) + .compareTo( Optional.ofNullable( + blankNodeOrdering.getOrder( right.asResource().asNode() ) ) + .orElse( Long.MAX_VALUE ) ); } - } else if (right.isResource()) { + } else if ( right.isResource() ) { return 1; // uris first } } - //fall-through for all other cases, especially if we don't have a blank node ordering - return left.toString().compareTo(right.toString()); + // fall-through for all other cases, especially if we don't have a blank node ordering + return left.toString().compareTo( right.toString() ); } } } diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/TurtleFormatter.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/TurtleFormatter.java index f915ab9b..ff36e757 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/TurtleFormatter.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/TurtleFormatter.java @@ -1,3 +1,19 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package cool.rdf.formatter; import cool.rdf.core.model.RdfPrefix; @@ -63,8 +79,8 @@ public class TurtleFormatter implements Function, BiConsumerEscape Sequences. *

- * ' (single quote) is not in the pattern, because we never write single quoted strings and therefore don't - * need to escape single quotes. + * ' (single quote) is not in the pattern, because we never write single quoted strings and therefore don't need to + * escape single quotes. *

*/ private static final Pattern STRING_ESCAPE_SEQUENCES = Pattern.compile( "(\r\n)|[\t\b\n\r\f\"\\\\]" ); @@ -103,17 +119,13 @@ public TurtleFormatter( final FormattingStyle style ) { case UTF_16_LE -> StandardCharsets.UTF_16LE; }; - prefixOrder = Comparator.>comparingInt( entry -> - style.prefixOrder.contains( entry.getKey() ) - ? style.prefixOrder.indexOf( entry.getKey() ) - : Integer.MAX_VALUE - ).thenComparing( Map.Entry::getKey ); + prefixOrder = Comparator.>comparingInt( entry -> style.prefixOrder.contains( entry.getKey() ) + ? style.prefixOrder.indexOf( entry.getKey() ) + : Integer.MAX_VALUE ).thenComparing( Map.Entry::getKey ); - objectOrder = Comparator.comparingInt( object -> - style.objectOrder.contains( object ) - ? style.objectOrder.indexOf( object ) - : Integer.MAX_VALUE - ); + objectOrder = Comparator.comparingInt( object -> style.objectOrder.contains( object ) + ? style.objectOrder.indexOf( object ) + : Integer.MAX_VALUE ); } private static List statements( final Model model ) { @@ -125,9 +137,7 @@ private static List statements( final Model model, final Property pre } /** - * Serializes the specified model as TTL according to the {@link TurtleFormatter}'s {@link FormattingStyle}. - * - *
+ * Serializes the specified model as TTL according to the {@link TurtleFormatter}'s {@link FormattingStyle}.
* Note: Using this method, ordering of blank nodes may differ between multiple runs using identical data. * * @param model the model to serialize. @@ -156,8 +166,7 @@ private void process( final String content, final ByteArrayOutputStream outputSt if ( style.charset == FormattingStyle.Charset.UTF_8_BOM ) { writeByteOrderMark( outputStream ); } - final BlankNodeOrderAwareTurtleParser.ParseResult result = - BlankNodeOrderAwareTurtleParser.parseModel( content ); + final BlankNodeOrderAwareTurtleParser.ParseResult result = BlankNodeOrderAwareTurtleParser.parseModel( content ); final Model model = result.getModel(); final BlankNodeMetadata blankNodeMetadata = result.getBlankNodeMetadata(); final PrefixMapping prefixMapping = buildPrefixMapping( model ); @@ -168,16 +177,15 @@ private void process( final String content, final ByteArrayOutputStream outputSt private void writeByteOrderMark( final OutputStream outputStream ) { try { - outputStream.write( new byte[]{ (byte) 0xEF, (byte) 0xBB, (byte) 0xBF } ); + outputStream.write( new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF } ); } catch ( final IOException exception ) { LOG.error( OUTPUT_ERROR_MESSAGE, exception ); } } /** - * Serializes the specified model as TTL according to the {@link TurtleFormatter}'s {@link FormattingStyle} - * and writes it to the specified outputStream. - *
+ * Serializes the specified model as TTL according to the {@link TurtleFormatter}'s {@link FormattingStyle} and + * writes it to the specified outputStream.
* Note: Using this method, ordering of blank nodes may differ between multiple runs using identical data. * * @param model the model to serialize. @@ -196,11 +204,9 @@ public void accept( final Model model, final OutputStream outputStream ) { private void doFormat( final Model model, final OutputStream outputStream, final PrefixMapping prefixMapping, final RDFNodeComparatorFactory RDFNodeComparatorFactory, final BlankNodeMetadata blankNodeMetadata ) { - final Comparator predicateOrder = Comparator.comparingInt( property -> - style.predicateOrder.contains( property ) - ? style.predicateOrder.indexOf( property ) - : Integer.MAX_VALUE - ).thenComparing( property -> prefixMapping.shortForm( property.getURI() ) ); + final Comparator predicateOrder = Comparator.comparingInt( property -> style.predicateOrder.contains( property ) + ? style.predicateOrder.indexOf( property ) + : Integer.MAX_VALUE ).thenComparing( property -> prefixMapping.shortForm( property.getURI() ) ); final State initialState = buildInitialState( model, outputStream, prefixMapping, predicateOrder, RDFNodeComparatorFactory, blankNodeMetadata ); final State prefixesWritten = writePrefixes( initialState ); @@ -214,8 +220,7 @@ private void doFormat( final Model model, final OutputStream outputStream, final private State writeAnonymousResources( final State state ) { State currentState = state; - final List sortedAnonymousIdentifiedResources = state - .identifiedAnonymousResources + final List sortedAnonymousIdentifiedResources = state.identifiedAnonymousResources .keySet() .stream() .sorted( state.getRDFNodeComparatorFactory().comparator() ) @@ -249,10 +254,10 @@ private State writeNamedResources( final State state, final List stat private List determineStatements( final Model model, final RDFNodeComparatorFactory rdfNodeComparatorFactory ) { - final Stream wellKnownSubjects = style.subjectOrder.stream().flatMap( subjectType -> - statements( model, RDF.type, subjectType ) - .stream() - .sorted( Comparator.comparing( Statement::getSubject, rdfNodeComparatorFactory.comparator() ) ) ); + final Stream wellKnownSubjects = style.subjectOrder.stream().flatMap( subjectType -> statements( model, RDF.type, + subjectType ) + .stream() + .sorted( Comparator.comparing( Statement::getSubject, rdfNodeComparatorFactory.comparator() ) ) ); final Stream otherSubjects = statements( model ).stream() .filter( statement -> !( statement.getPredicate().equals( RDF.type ) @@ -288,8 +293,8 @@ private State buildInitialState( final Model model, final OutputStream outputStr } /** - * Anonymous resources that are referred to more than once need to be given an internal id and - * can not be serialized using [ ] notation. + * Anonymous resources that are referred to more than once need to be given an internal id and can not be serialized + * using [ ] notation. * * @param model the input model * @param currentState the state @@ -303,15 +308,14 @@ private Set anonymousResourcesThatNeedAnId( final Model model, final S .map( RDFNode::asResource ) .filter( RDFNode::isAnon ).collect( Collectors.toSet() ); candidates.removeAll( currentState.getBlankNodeMetadata().getLabeledBlankNodes() ); - final List candidatesInOrder = - Stream.concat( - currentState.getBlankNodeMetadata().getLabeledBlankNodes() - .stream() - .sorted( currentState.getRDFNodeComparatorFactory().comparator() ), - candidates - .stream() - .sorted( currentState.getRDFNodeComparatorFactory().comparator() ) ) - .toList(); + final List candidatesInOrder = Stream.concat( + currentState.getBlankNodeMetadata().getLabeledBlankNodes() + .stream() + .sorted( currentState.getRDFNodeComparatorFactory().comparator() ), + candidates + .stream() + .sorted( currentState.getRDFNodeComparatorFactory().comparator() ) ) + .toList(); for ( final Resource candidate : candidatesInOrder ) { if ( identifiedResources.contains( candidate ) ) { continue; @@ -358,8 +362,7 @@ private PrefixMapping buildPrefixMapping( final Model model ) { private State writePrefixes( final State state ) { final Map prefixes = state.prefixMapping.getNsPrefixMap(); - final int maxPrefixLength = - prefixes.keySet().stream().map( String::length ).max( Integer::compareTo ).orElse( 0 ); + final int maxPrefixLength = prefixes.keySet().stream().map( String::length ).max( Integer::compareTo ).orElse( 0 ); final String prefixFormat = switch ( style.alignPrefixes ) { case OFF -> "@prefix %s: <%s>" + beforeDot + "." + endOfLine; case LEFT -> "@prefix %-" + maxPrefixLength + "s: <%s>" + beforeDot + "." + endOfLine; @@ -470,7 +473,7 @@ private boolean isList( final RDFNode node, final State state ) { if ( !node.isResource() ) { return false; } - if( node.equals( RDF.nil ) ) { + if ( node.equals( RDF.nil ) ) { return true; } final boolean listNodeHasAdditionalTriples = state.model.listStatements( node.asResource(), null, (RDFNode) null ) @@ -497,10 +500,9 @@ private State writeResource( final Resource resource, final State state ) { } private State writeList( final Resource resource, final State state ) { - final FormattingStyle.GapStyle afterOpeningParenthesis = - style.wrapListItems == FormattingStyle.WrappingStyle.ALWAYS - ? FormattingStyle.GapStyle.NOTHING - : style.afterOpeningParenthesis; + final FormattingStyle.GapStyle afterOpeningParenthesis = style.wrapListItems == FormattingStyle.WrappingStyle.ALWAYS + ? FormattingStyle.GapStyle.NOTHING + : style.afterOpeningParenthesis; final State opened = writeDelimiter( "(", style.beforeOpeningParenthesis, afterOpeningParenthesis, continuationIndent( state.indentationLevel ), state ); final java.util.List elementList = resource.as( RDFList.class ).asJavaList(); @@ -531,8 +533,7 @@ private State writeListElement( final RDFNode element, final boolean firstElemen case FOR_LONG_LINES: final int alignmentAfterElementIsWritten = writeRdfNode( element, state.withOutputStream( OutputStream.nullOutputStream() ) ).alignment; - final boolean wouldElementExceedLineLength = - ( alignmentAfterElementIsWritten + 1 ) > style.maxLineLength; + final boolean wouldElementExceedLineLength = ( alignmentAfterElementIsWritten + 1 ) > style.maxLineLength; yield writeRdfNode( element, wouldElementExceedLineLength ? state.newLine().write( continuationIndent( state.indentationLevel ) ) : ( firstElement || state.getLastCharacter().equals( " " ) ? state : state.write( " " ) ) ); @@ -583,8 +584,8 @@ private String uriResource( final Resource resource, final State state ) { } /** - * Unfortunately, the logic in {@link PrefixMapAdapter#abbrev(String)} is broken and won't return a prefix - * even if one exists in the wrapped map; and the class is final, so we can't overwrite the method. + * Unfortunately, the logic in {@link PrefixMapAdapter#abbrev(String)} is broken and won't return a prefix even if + * one exists in the wrapped map; and the class is final, so we can't overwrite the method. */ static class CustomPrefixMap extends PrefixMapBase implements PrefixMap { private final PrefixMapping mapping; @@ -679,23 +680,23 @@ private String quoteAndEscape( final RDFNode node ) { final String quote = switch ( style.quoteStyle ) { case ALWAYS_SINGE_QUOTES -> "\""; case ALWAYS_TRIPLE_QUOTES -> "\"\"\""; - case TRIPLE_QUOTES_FOR_MULTILINE -> (value.contains( "\n" ) || value.contains("\r"))? "\"\"\"" : "\""; + case TRIPLE_QUOTES_FOR_MULTILINE -> ( value.contains( "\n" ) || value.contains( "\r" ) ) ? "\"\"\"" : "\""; }; - final Map characterReplacements = Map.of( "\t", "\\\\t", "\b", "\\\\b", - "\r", quote.equals( "\"" ) ? "\\\\r": "\n", // in multiline strings that were read with mac style endings, replace \r with \n - "\r\n", quote.equals( "\"" ) ? "\\\\r\\\\n": "\n", // in multiline strings that were read with windows style endings, replace \r\n with \n + "\r", quote.equals( "\"" ) ? "\\\\r" : "\n", // in multiline strings that were read with mac style endings, + // replace \r with \n + "\r\n", quote.equals( "\"" ) ? "\\\\r\\\\n" : "\n", // in multiline strings that were read with windows + // style endings, replace \r\n with \n "\f", "\\\\f", "\n", quote.equals( "\"" ) ? "\\\\n" : "\n", // Don't escape line breaks in triple-quoted strings "\"", quote.equals( "\"" ) ? "\\\\\"" : "\"", // Don't escape quotes in triple-quoted strings - "\\", "\\\\\\\\" - ); + "\\", "\\\\\\\\" ); - final String escapedValue = STRING_ESCAPE_SEQUENCES.matcher( value ).replaceAll( match -> - characterReplacements.getOrDefault( match.group(), match.group() ) ); + final String escapedValue = STRING_ESCAPE_SEQUENCES.matcher( value ).replaceAll( match -> characterReplacements.getOrDefault( match + .group(), match.group() ) ); // Special case: If the last character in the triple-quoted string is a quote, it must be escaped // See https://github.com/atextor/turtle-formatter/issues/9 @@ -747,8 +748,8 @@ private State writeSubject( final Resource resource, final State state ) { // predicates and objects final Set properties = resource.listProperties().mapWith( Statement::getPredicate ).toSet(); - final int maxPropertyWidth = properties.stream().map( property -> - uriResource( property, state ) ).map( String::length ).max( Integer::compareTo ).orElse( 0 ); + final int maxPropertyWidth = properties.stream().map( property -> uriResource( property, state ) ).map( String::length ).max( + Integer::compareTo ).orElse( 0 ); int index = 0; State currentState = gapAfterSubject.addIndentationLevel(); @@ -769,8 +770,7 @@ private State writeSubject( final Resource resource, final State state ) { private State writeProperty( final Resource subject, final Property predicate, final boolean firstProperty, final boolean lastProperty, final int alignment, final String gapAfterPredicate, final State state ) { - final Set objects = - subject.listProperties( predicate ).mapWith( Statement::getObject ).toSet(); + final Set objects = subject.listProperties( predicate ).mapWith( Statement::getObject ).toSet(); final boolean useComma = ( style.useCommaByDefault && !style.noCommaForPredicate.contains( predicate ) ) || ( !style.useCommaByDefault && style.commaForPredicate.contains( predicate ) ); @@ -829,21 +829,18 @@ private State writeProperty( final Resource subject, final Property predicate, f } final boolean listWritten = isList && style.afterClosingParenthesis == FormattingStyle.GapStyle.NOTHING; - final boolean omitSpaceBeforeDelimiter = - object.isResource() - && object.isAnon() - && !listWritten - && !currentState.identifiedAnonymousResources.containsKey( object.asResource() ); + final boolean omitSpaceBeforeDelimiter = object.isResource() + && object.isAnon() + && !listWritten + && !currentState.identifiedAnonymousResources.containsKey( object.asResource() ); if ( lastProperty && lastObject && objectWritten.indentationLevel == 1 && !inBrackets ) { currentState = writeDot( objectWritten, omitSpaceBeforeDelimiter ).newLine(); index++; continue; } final boolean doAlign = style.alignPredicates || subject.isAnon(); - final boolean moreIdenticalPredicatesRemaining = - subject.listProperties( predicate ).toList().size() > 1 && !lastObject; - final boolean isAnonOrLastObject = - ( subject.isAnon() || lastObject ) && !moreIdenticalPredicatesRemaining; + final boolean moreIdenticalPredicatesRemaining = subject.listProperties( predicate ).toList().size() > 1 && !lastObject; + final boolean isAnonOrLastObject = ( subject.isAnon() || lastObject ) && !moreIdenticalPredicatesRemaining; final String nextLineIndentation = doAlign && isAnonOrLastObject ? "" : indent( objectWritten.indentationLevel ); @@ -940,7 +937,6 @@ private class State { String lastCharacter; - public State( final OutputStream outputStream, final Model model, final Comparator predicateOrder, final PrefixMapping prefixMapping, final RDFNodeComparatorFactory RDFNodeComparatorFactory, final BlankNodeMetadata blankNodeMetadata ) { diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java index 6084b633..83c000bf 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java @@ -1,15 +1,33 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package cool.rdf.formatter.blanknode; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import org.apache.jena.graph.Node; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.RDFNode; import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.Statement; -import org.apache.jena.vocabulary.RDF; - -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; /** * A lookup table for each blank node's order in a TTL file. @@ -23,15 +41,15 @@ public class BlankNodeMetadata { public BlankNodeMetadata() { } - public void linkGraphNodesToModelResources(Model model ){ - this.labeledBlankNodes.addAll(model.listStatements() - .toList() - .stream() - .flatMap(s -> Stream.of(s.getSubject(), s.getObject())) - .filter(RDFNode::isAnon) - .filter(a -> this.blankNodeLabels.containsKey(a.asNode())) - .map(RDFNode::asResource) - .collect(Collectors.toSet())); + public void linkGraphNodesToModelResources( final Model model ) { + labeledBlankNodes.addAll( model.listStatements() + .toList() + .stream() + .flatMap( s -> Stream.of( s.getSubject(), s.getObject() ) ) + .filter( RDFNode::isAnon ) + .filter( a -> blankNodeLabels.containsKey( a.asNode() ) ) + .map( RDFNode::asResource ) + .collect( Collectors.toSet() ) ); } @@ -40,40 +58,42 @@ public static BlankNodeMetadata gotNothing() { } /** - * Returns the order of the specified node, if it has been added previously via - * {@link #registerNewBlankNode(Node)}, or null. + * Returns the order of the specified node, if it has been added previously via {@link #registerNewBlankNode(Node)}, + * or null. + * * @param node the node to look up * @return the 0-based order of the {@code node} (or null if it has not been registered) */ - public Long getOrder(Node node) { - return blankNodeIndex.get(node); + public Long getOrder( final Node node ) { + return blankNodeIndex.get( node ); } /** * If the specified {@code node} is a labeled blank node, the label is returned. + * * @param node * @return the label or null. */ - public String getLabel(Node node) { - return blankNodeLabels.get(node); + public String getLabel( final Node node ) { + return blankNodeLabels.get( node ); } - void registerNewBlankNode(Node blankNode) { - if (blankNode.isBlank() && ! blankNodeIndex.containsKey(blankNode)){ - this.blankNodeIndex.put(blankNode, nextIndex++); + void registerNewBlankNode( final Node blankNode ) { + if ( blankNode.isBlank() && !blankNodeIndex.containsKey( blankNode ) ) { + blankNodeIndex.put( blankNode, nextIndex++ ); } } - void registerNewBlankNode(Node blankNode, String label) { - registerNewBlankNode(blankNode); - this.blankNodeLabels.put(blankNode, label); + void registerNewBlankNode( final Node blankNode, final String label ) { + registerNewBlankNode( blankNode ); + blankNodeLabels.put( blankNode, label ); } public Set getLabeledBlankNodes() { - return Collections.unmodifiableSet(this.labeledBlankNodes); + return Collections.unmodifiableSet( labeledBlankNodes ); } public Set getAllBlankNodeLabels() { - return Collections.unmodifiableSet(new HashSet<>(this.blankNodeLabels.values())); + return Collections.unmodifiableSet( new HashSet<>( blankNodeLabels.values() ) ); } } diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java index 338d8d89..d19589b7 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java @@ -1,5 +1,25 @@ +/* + * Copyright Andreas Textor + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package cool.rdf.formatter.blanknode; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.Reader; + import org.apache.jena.atlas.web.ContentType; import org.apache.jena.graph.Graph; import org.apache.jena.graph.Node; @@ -10,7 +30,6 @@ import org.apache.jena.riot.RDFParser; import org.apache.jena.riot.RDFParserRegistry; import org.apache.jena.riot.ReaderRIOT; -import org.apache.jena.riot.ReaderRIOTFactory; import org.apache.jena.riot.lang.LabelToNode; import org.apache.jena.riot.lang.LangRIOT; import org.apache.jena.riot.lang.RiotParsers; @@ -21,79 +40,79 @@ import org.apache.jena.riot.tokens.TokenType; import org.apache.jena.sparql.util.Context; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.Reader; - public class BlankNodeOrderAwareTurtleParser { /** - * Parses the TTL content and returns a {@link ParseResult}, containing the - * new {@link Model} and a {@link BlankNodeMetadata} object that makes the ordering of the - * blank nodes in the original content accessible for further processing. + * Parses the TTL content and returns a {@link ParseResult}, containing the new {@link Model} and a + * {@link BlankNodeMetadata} object that makes the ordering of the blank nodes in the original content + * accessible for further processing. + * * @param content RDF in TTL format * @return the parse result and the blank node ordering */ - public static ParseResult parseModel(String content) { - BlankNodeMetadata bnodeMetadata = new BlankNodeMetadata(); + public static ParseResult parseModel( final String content ) { + final BlankNodeMetadata bnodeMetadata = new BlankNodeMetadata(); - Lang TTL_bn = LangBuilder.create("TTL_BN", "text/bogus") - .build(); - RDFParserRegistry.registerLangTriples(TTL_bn, new ReaderRIOTFactory() { - @Override public ReaderRIOT create(Lang language, ParserProfile profile) { - ParserProfile profileWrapper = new ParserProfileWrapper(profile) { - @Override public Node createBlankNode(Node scope, String label, long line, long col) { - Node blank = get().createBlankNode(scope, label, line, col); - bnodeMetadata.registerNewBlankNode(blank, label); - return blank; - } + final Lang TTL_bn = LangBuilder.create( "TTL_BN", "text/bogus" ) + .build(); + RDFParserRegistry.registerLangTriples( TTL_bn, ( language, profile ) -> { + final ParserProfile profileWrapper = new ParserProfileWrapper( profile ) { + @Override + public Node createBlankNode( final Node scope, final String label, final long line, final long col ) { + final Node blank = get().createBlankNode( scope, label, line, col ); + bnodeMetadata.registerNewBlankNode( blank, label ); + return blank; + } - @Override public Node createBlankNode(Node scope, long line, long col) { - Node blank = get().createBlankNode(scope, line, col); - bnodeMetadata.registerNewBlankNode(blank); - return blank; - } + @Override + public Node createBlankNode( final Node scope, final long line, final long col ) { + final Node blank = get().createBlankNode( scope, line, col ); + bnodeMetadata.registerNewBlankNode( blank ); + return blank; + } - @Override - public Node create(Node currentGraph, Token token) { - // Dispatches to the underlying ParserFactory operation - long line = token.getLine(); - long col = token.getColumn(); - String str = token.getImage(); - if (token.getType() == TokenType.BNODE) { - return createBlankNode(currentGraph, str, line, col); - } - return get().create(currentGraph, token); + @Override + public Node create( final Node currentGraph, final Token token ) { + // Dispatches to the underlying ParserFactory operation + final long line = token.getLine(); + final long col = token.getColumn(); + final String str = token.getImage(); + if ( token.getType() == TokenType.BNODE ) { + return createBlankNode( currentGraph, str, line, col ); } + return get().create( currentGraph, token ); + } - }; - return new ReaderRIOT() { - @Override public void read(InputStream in, String baseURI, ContentType ct, StreamRDF output, - Context context) { - LangRIOT parser = RiotParsers.createParser(in, Lang.TTL, output, profileWrapper); - parser.parse(); - } + }; + return new ReaderRIOT() { + @Override + public void read( final InputStream in, final String baseURI, final ContentType ct, final StreamRDF output, + final Context context ) { + final LangRIOT parser = RiotParsers.createParser( in, Lang.TTL, output, profileWrapper ); + parser.parse(); + } - @Override public void read(Reader reader, String baseURI, ContentType ct, StreamRDF output, - Context context) { - LangRIOT parser = RiotParsers.createParser(reader, Lang.TTL, output, profileWrapper); - parser.parse(); - } - }; - } - }); - Graph graph = RDFParser.source(new ByteArrayInputStream(content.getBytes())).labelToNode(LabelToNode.createUseLabelAsGiven()).lang( - TTL_bn).toGraph(); - RDFParserRegistry.removeRegistration(TTL_bn); - Model model = ModelFactory.createModelForGraph(graph); - bnodeMetadata.linkGraphNodesToModelResources(model); - return new ParseResult(model, bnodeMetadata); + @Override + public void read( final Reader reader, final String baseURI, final ContentType ct, final StreamRDF output, + final Context context ) { + final LangRIOT parser = RiotParsers.createParser( reader, Lang.TTL, output, profileWrapper ); + parser.parse(); + } + }; + } ); + final Graph graph = RDFParser.source( new ByteArrayInputStream( content.getBytes() ) ).labelToNode( LabelToNode + .createUseLabelAsGiven() ) + .lang( TTL_bn ).toGraph(); + RDFParserRegistry.removeRegistration( TTL_bn ); + final Model model = ModelFactory.createModelForGraph( graph ); + bnodeMetadata.linkGraphNodesToModelResources( model ); + return new ParseResult( model, bnodeMetadata ); } public static class ParseResult { private final Model model; private final BlankNodeMetadata blankNodeMetadata; - public ParseResult(Model model, BlankNodeMetadata blankNodeMetadata) { + public ParseResult( final Model model, final BlankNodeMetadata blankNodeMetadata ) { this.model = model; this.blankNodeMetadata = blankNodeMetadata; } diff --git a/cool-rdf-infer/src/main/java/cool/rdf/infer/Configuration.java b/cool-rdf-infer/src/main/java/cool/rdf/infer/Configuration.java index c96e6acd..45ca2802 100644 --- a/cool-rdf-infer/src/main/java/cool/rdf/infer/Configuration.java +++ b/cool-rdf-infer/src/main/java/cool/rdf/infer/Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-infer/src/main/java/cool/rdf/infer/Inferrer.java b/cool-rdf-infer/src/main/java/cool/rdf/infer/Inferrer.java index d30221f6..a0938379 100644 --- a/cool-rdf-infer/src/main/java/cool/rdf/infer/Inferrer.java +++ b/cool-rdf-infer/src/main/java/cool/rdf/infer/Inferrer.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,8 @@ public class Inferrer { private static final Logger LOG = LoggerFactory.getLogger( Inferrer.class ); /** - * Writes an inferred OWL document given by an input URL, to an output stream using a writing/formatting configuration + * Writes an inferred OWL document given by an input URL, to an output stream using a writing/formatting + * configuration * * @param inputUrl the input URL * @param output the output stream @@ -84,7 +85,8 @@ public Try infer( final URL inputUrl, final OutputStream output, final Con } /** - * Writes an inferred OWL document given by an input stream, to an output stream using a writing/formatting configuration + * Writes an inferred OWL document given by an input stream, to an output stream using a writing/formatting + * configuration * * @param input the input stream * @param output the output stream diff --git a/cool-rdf-write/src/main/java/cool/rdf/write/Configuration.java b/cool-rdf-write/src/main/java/cool/rdf/write/Configuration.java index 8eb9d887..ae5100a7 100644 --- a/cool-rdf-write/src/main/java/cool/rdf/write/Configuration.java +++ b/cool-rdf-write/src/main/java/cool/rdf/write/Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cool-rdf-write/src/main/java/cool/rdf/write/RdfWriter.java b/cool-rdf-write/src/main/java/cool/rdf/write/RdfWriter.java index 0e4cc72f..e2b13136 100644 --- a/cool-rdf-write/src/main/java/cool/rdf/write/RdfWriter.java +++ b/cool-rdf-write/src/main/java/cool/rdf/write/RdfWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 Andreas Textor + * Copyright Andreas Textor * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,8 @@ import java.net.http.HttpResponse; /** - * The RDF Writer is used to serialize RDF documents into various formats, while using configurable formatting for RDF/Turtle - * specifically, using the {@link TurtleFormatter}. + * The RDF Writer is used to serialize RDF documents into various formats, while using configurable formatting for + * RDF/Turtle specifically, using the {@link TurtleFormatter}. */ public class RdfWriter { /** diff --git a/pom.xml b/pom.xml index c278b34b..e9840489 100644 --- a/pom.xml +++ b/pom.xml @@ -66,6 +66,7 @@ false false false + 4.38 2.5.11 @@ -581,7 +582,6 @@ spotless-maven-plugin - @@ -598,12 +598,14 @@ src/main/java/**/*.java - 4.38 + ${eclipse-code-formatter.version} ${maven.multiModuleProjectDirectory}/.development/eclipse-code-style.xml ${maven.multiModuleProjectDirectory}/.development/license-header + +
From c7bf019986dc5708a36b09c37eccb4b440ce04f6 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Thu, 1 Jan 2026 23:09:11 +0100 Subject: [PATCH 278/280] Update to Java 25 and third party versions This commit replaces the usage of java.lang.SecurityManager (which was used for capturing calls to System.exit() from the CLI) with a Mockito Spy object of java.lang.Runtime. Dependency update does not include GraalVM and Jena. --- cool-rdf-cli/pom.xml | 10 +- .../java/cool/rdf/cli/AbstractCommand.java | 61 +++++++---- .../src/main/java/cool/rdf/cli/Cool.java | 14 +-- .../main/java/cool/rdf/cli/CoolDiagram.java | 4 + .../src/main/java/cool/rdf/cli/CoolInfer.java | 4 + .../src/main/java/cool/rdf/cli/CoolWrite.java | 4 + .../src/test/java/cool/rdf/cli/CliRunner.java | 96 ++++++++--------- docs/pom.xml | 2 +- pom.xml | 100 +++++++++--------- 9 files changed, 167 insertions(+), 128 deletions(-) diff --git a/cool-rdf-cli/pom.xml b/cool-rdf-cli/pom.xml index 620c9a39..5e0c84eb 100644 --- a/cool-rdf-cli/pom.xml +++ b/cool-rdf-cli/pom.xml @@ -83,6 +83,10 @@ com.fasterxml.jackson.core jackson-databind + + org.slf4j + slf4j-api + ch.qos.logback logback-classic @@ -124,6 +128,11 @@ classgraph test + + org.mockito + mockito-core + test + @@ -184,7 +193,6 @@ ${build.time.sources} - ${generated.sources} diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/AbstractCommand.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/AbstractCommand.java index 1578daf4..5d40ef9d 100644 --- a/cool-rdf-cli/src/main/java/cool/rdf/cli/AbstractCommand.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/AbstractCommand.java @@ -18,13 +18,31 @@ import com.google.common.collect.ImmutableSet; import io.vavr.control.Try; +import org.semanticweb.owlapi.dlsyntax.parser.DLSyntaxOWLParserFactory; +import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory; +import org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory; +import org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParserFactory; +import org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory; import org.semanticweb.owlapi.io.OWLParserFactory; +import org.semanticweb.owlapi.krss2.parser.KRSS2OWLParserFactory; +import org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory; +import org.semanticweb.owlapi.latex.renderer.LatexStorerFactory; +import org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxOntologyParserFactory; +import org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory; import org.semanticweb.owlapi.model.OWLDataFactory; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.OWLOntologyFactory; import org.semanticweb.owlapi.model.OWLOntologyManager; import org.semanticweb.owlapi.model.OWLStorerFactory; +import org.semanticweb.owlapi.oboformat.OBOFormatOWLAPIParserFactory; +import org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory; +import org.semanticweb.owlapi.owlxml.parser.OWLXMLParserFactory; +import org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory; +import org.semanticweb.owlapi.rdf.rdfxml.parser.RDFXMLParserFactory; +import org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory; +import org.semanticweb.owlapi.rdf.turtle.parser.TurtleOntologyParserFactory; +import org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory; import org.slf4j.Logger; import picocli.CommandLine; import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; @@ -48,12 +66,17 @@ * Base class for commands that bundles common functionality */ public abstract class AbstractCommand { + protected final Runtime runtime; + + protected AbstractCommand( final Runtime runtime ) { + this.runtime = runtime; + } /** * Will exit the program with status code 1 */ protected void commandFailed() { - System.exit( 1 ); + runtime.exit( 1 ); } /** @@ -129,14 +152,14 @@ protected Try openInput( final String input ) { */ protected OWLOntologyManager createOWLOntologyManager() { final ImmutableSet parserFactories = ImmutableSet.builder() - .add( new org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxOntologyParserFactory() ) - .add( new org.semanticweb.owlapi.krss2.parser.KRSS2OWLParserFactory() ) - .add( new org.semanticweb.owlapi.rdf.turtle.parser.TurtleOntologyParserFactory() ) - .add( new org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParserFactory() ) - .add( new org.semanticweb.owlapi.owlxml.parser.OWLXMLParserFactory() ) - .add( new org.semanticweb.owlapi.rdf.rdfxml.parser.RDFXMLParserFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.parser.DLSyntaxOWLParserFactory() ) - .add( new org.semanticweb.owlapi.oboformat.OBOFormatOWLAPIParserFactory() ) + .add( new ManchesterOWLSyntaxOntologyParserFactory() ) + .add( new KRSS2OWLParserFactory() ) + .add( new TurtleOntologyParserFactory() ) + .add( new OWLFunctionalSyntaxOWLParserFactory() ) + .add( new OWLXMLParserFactory() ) + .add( new RDFXMLParserFactory() ) + .add( new DLSyntaxOWLParserFactory() ) + .add( new OBOFormatOWLAPIParserFactory() ) .build(); final Set ontologyFactories = ImmutableSet.builder() @@ -145,16 +168,16 @@ protected OWLOntologyManager createOWLOntologyManager() { @SuppressWarnings( "SpellCheckingInspection" ) final Set storerFactories = ImmutableSet.builder() - .add( new org.semanticweb.owlapi.rdf.rdfxml.renderer.RDFXMLStorerFactory() ) - .add( new org.semanticweb.owlapi.owlxml.renderer.OWLXMLStorerFactory() ) - .add( new org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.krss2.renderer.KRSS2OWLSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.rdf.turtle.renderer.TurtleStorerFactory() ) - .add( new org.semanticweb.owlapi.latex.renderer.LatexStorerFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxHTMLStorerFactory() ) - .add( new org.semanticweb.owlapi.dlsyntax.renderer.DLSyntaxStorerFactory() ) - .add( new org.semanticweb.owlapi.oboformat.OBOFormatStorerFactory() ) + .add( new RDFXMLStorerFactory() ) + .add( new OWLXMLStorerFactory() ) + .add( new FunctionalSyntaxStorerFactory() ) + .add( new ManchesterSyntaxStorerFactory() ) + .add( new KRSS2OWLSyntaxStorerFactory() ) + .add( new TurtleStorerFactory() ) + .add( new LatexStorerFactory() ) + .add( new DLSyntaxHTMLStorerFactory() ) + .add( new DLSyntaxStorerFactory() ) + .add( new OBOFormatStorerFactory() ) .build(); final OWLDataFactory dataFactory = new OWLDataFactoryImpl(); diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/Cool.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/Cool.java index bce1c603..cb1a0748 100644 --- a/cool-rdf-cli/src/main/java/cool/rdf/cli/Cool.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/Cool.java @@ -46,6 +46,8 @@ public class Cool implements Runnable { * The name of the top level command */ private static final Logger LOG = LoggerFactory.getLogger( Cool.class ); + @SuppressWarnings( "FieldMayBeFinal" ) + private static Runtime runtime = Runtime.getRuntime(); private static void printError( final CommandLine commandLine, final Exception exception ) { final Level logLevel = ( (LoggingMixin) commandLine.getMixins().values().iterator().next() ).calcLogLevel(); @@ -108,9 +110,9 @@ public static void main( final String[] args ) { LogManager.getLogManager().reset(); final List commands = List.of( - new CoolDiagram(), - new CoolWrite(), - new CoolInfer() ); + new CoolDiagram( runtime ), + new CoolWrite( runtime ), + new CoolInfer( runtime ) ); final CommandLine cmd = commands.foldLeft( new Cool().commandLine, CommandLine::addSubcommand ) .setParameterExceptionHandler( PARAMETER_EXCEPTION_HANDLER ) .setExecutionExceptionHandler( EXECUTION_EXCEPTION_HANDLER ) @@ -119,19 +121,19 @@ public static void main( final String[] args ) { commands.forEach( command -> command.registerTypeConverters( cmd ) ); final int resultCode = cmd.execute( args ); - System.exit( resultCode ); + runtime.exit( resultCode ); } @Override public void run() { if ( helpRequested ) { - System.exit( 0 ); + runtime.exit( 0 ); } if ( version ) { System.out.printf( "%s %s%n commit: %s%n build date: %s%n", COMMAND_NAME, Version.VERSION, Version.COMMIT_ID.substring( 0, 7 ), Version.BUILD_DATE ); - System.exit( 0 ); + runtime.exit( 0 ); } System.out.println( commandLine.getHelp().fullSynopsis() ); diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolDiagram.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolDiagram.java index 1f2eb6ac..d196febf 100644 --- a/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolDiagram.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolDiagram.java @@ -131,6 +131,10 @@ public class CoolDiagram extends AbstractCommand implements Runnable { index = "1" ) private String output; + protected CoolDiagram( final Runtime runtime ) { + super( runtime ); + } + @Override public void run() { final MappingConfiguration mappingConfig = DefaultMappingConfiguration.builder().build(); diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolInfer.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolInfer.java index 858cfb56..0f2a04cd 100644 --- a/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolInfer.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolInfer.java @@ -71,6 +71,10 @@ public class CoolInfer extends AbstractCommand implements Runnable { index = "1" ) private String output; + protected CoolInfer( final Runtime runtime ) { + super( runtime ); + } + @Override public void run() { final Configuration.ConfigurationBuilder configurationBuilder = Configuration.builder(); diff --git a/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolWrite.java b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolWrite.java index af020f6a..23402bb7 100644 --- a/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolWrite.java +++ b/cool-rdf-cli/src/main/java/cool/rdf/cli/CoolWrite.java @@ -243,6 +243,10 @@ public class CoolWrite extends AbstractCommand implements Runnable { index = "1" ) private String output; + protected CoolWrite( final Runtime runtime ) { + super( runtime ); + } + @Override public void run() { final FormattingStyle style = FormattingStyle.builder() diff --git a/cool-rdf-cli/src/test/java/cool/rdf/cli/CliRunner.java b/cool-rdf-cli/src/test/java/cool/rdf/cli/CliRunner.java index f2e6719c..5676f8db 100644 --- a/cool-rdf-cli/src/test/java/cool/rdf/cli/CliRunner.java +++ b/cool-rdf-cli/src/test/java/cool/rdf/cli/CliRunner.java @@ -16,8 +16,9 @@ package cool.rdf.cli; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.spy; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -26,10 +27,10 @@ import java.io.InputStream; import java.io.PrintStream; import java.io.Serial; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; -import java.security.Permission; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -40,15 +41,15 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Convenient test runner to execute a command line interface either via main class, executable jar or native binary. - * Arguments and stdin can be provided, return code, stderr and stdout are captured. - * This class uses {@link System#getSecurityManager()} and {@link System#setSecurityManager(SecurityManager)} that - * are deprecated as of Java 17. However, until - * JDK-8199704 is addressed, - * we have still to rely on it. + * Arguments and stdin can be provided, return code, stderr and stdout are captured. This class uses Mockito to capture + * calls to {@link Runtime#exit(int)}: It relies on the tested class having a non-final field "java.lang.Runtime + * runtime" which is used to calling exit(). */ -@SuppressWarnings( "removal" ) public class CliRunner { private static final Logger LOG = LoggerFactory.getLogger( CliRunner.class ); @@ -57,7 +58,7 @@ public class CliRunner { * * @param raw the raw byte content */ - record StreamContent( byte[] raw ) { + public record StreamContent( byte[] raw ) { /** * Returns the stream content as UTF-8 string * @@ -77,7 +78,7 @@ public String cleaned() { } } - record ExecArguments( List arguments, StreamContent stdin, File workingDirectory ) { + public record ExecArguments( List arguments, StreamContent stdin, File workingDirectory ) { public ExecArguments( final List arguments, final StreamContent stdin ) { this( arguments, stdin, new File( "." ).getAbsoluteFile() ); } @@ -91,39 +92,18 @@ public ExecArguments( final String... arguments ) { } } - record Result( int exitStatus, StreamContent stdOut, StreamContent stdErr ) { - } - - private static class CaptureSystemExitSecurityManager extends SecurityManager { - private final SecurityManager delegateSecurityManager; - - private int exitCode = 0; - - CaptureSystemExitSecurityManager( final SecurityManager delegateSecurityManager ) { - this.delegateSecurityManager = delegateSecurityManager; - } - - int getExitCode() { - return exitCode; - } - - @Override - public void checkPermission( final Permission permission ) { - if ( delegateSecurityManager != null ) { - delegateSecurityManager.checkPermission( permission ); - } - } - - @Override - public void checkExit( final int i ) { - exitCode = i; - throw new SystemExitCapturedException(); - } + public record Result( int exitStatus, StreamContent stdOut, StreamContent stdErr ) { } private static class SystemExitCapturedException extends RuntimeException { @Serial private static final long serialVersionUID = 6080552325336609875L; + + private final int returnCode; + + private SystemExitCapturedException( final int returnCode ) { + this.returnCode = returnCode; + } } private record StreamCollector( InputStream in ) implements Callable { @@ -143,10 +123,6 @@ public ByteArrayOutputStream call() throws Exception { * @return the execution result */ public static Result runMainClass( final Class clazz, final ExecArguments execArguments ) { - final SecurityManager originalSecurityManager = System.getSecurityManager(); - final CaptureSystemExitSecurityManager securityManager = new CaptureSystemExitSecurityManager( originalSecurityManager ); - System.setSecurityManager( securityManager ); - final PrintStream originalStdout = System.out; final PrintStream originalStderr = System.err; final InputStream originalStdin = System.in; @@ -156,8 +132,7 @@ public static Result runMainClass( final Class clazz, final ExecArguments exe final ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); final ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream(); final PrintStream outStream = new PrintStream( stdoutBuffer ); - final PrintStream errStream = new PrintStream( stderrBuffer ) - ) { + final PrintStream errStream = new PrintStream( stderrBuffer ) ) { System.setOut( outStream ); System.setErr( errStream ); @@ -167,21 +142,38 @@ public static Result runMainClass( final Class clazz, final ExecArguments exe System.setProperty( "user.dir", execArguments.workingDirectory().getAbsolutePath() ); final Method method = clazz.getMethod( "main", String[].class ); + + // Mock runtime for the tested class, in order to capture + // calls to System.exit() + try { + final Runtime spyRuntime = spy( Runtime.getRuntime() ); + final Field runtime = clazz.getDeclaredField( "runtime" ); + runtime.setAccessible( true ); + runtime.set( null, spyRuntime ); + doThrow( new SystemExitCapturedException( -1 ) ).when( spyRuntime ).exit( anyInt() ); + doThrow( new SystemExitCapturedException( 1 ) ).when( spyRuntime ).exit( 1 ); + doThrow( new SystemExitCapturedException( 0 ) ).when( spyRuntime ).exit( 0 ); + } catch ( final NoSuchFieldException exception ) { + throw new RuntimeException( exception ); + } + + int returnCode = 0; try { method.invoke( null, (Object) execArguments.arguments().toArray( new String[0] ) ); } catch ( final InvocationTargetException exception ) { // Ignore System.exit, throw everything else - if ( !exception.getCause().getClass().equals( SystemExitCapturedException.class ) ) { + if ( exception.getCause() instanceof SystemExitCapturedException systemExitCapturedException ) { + returnCode = systemExitCapturedException.returnCode; + } else { throw new RuntimeException( exception ); } } - return new Result( securityManager.getExitCode(), + return new Result( returnCode, new StreamContent( stdoutBuffer.toByteArray() ), new StreamContent( stderrBuffer.toByteArray() ) ); } catch ( final NoSuchMethodException | IllegalAccessException | IOException exception ) { throw new RuntimeException( exception ); } finally { - System.setSecurityManager( originalSecurityManager ); System.setOut( originalStdout ); System.setErr( originalStderr ); if ( execArguments.stdin().raw().length > 0 ) { @@ -191,7 +183,6 @@ public static Result runMainClass( final Class clazz, final ExecArguments exe } } - /** * Executes a command line interface via its executable jar * @@ -206,8 +197,7 @@ public static Result runJar( final File jarFile, final ExecArguments execArgumen final List javaExecArguments = Stream.of( jvmArguments.stream(), Stream.of( "-jar", jarFile.toString() ), - execArguments.arguments().stream() - ).flatMap( Function.identity() ).toList(); + execArguments.arguments().stream() ).flatMap( Function.identity() ).toList(); return runBinary( javaBinary, new ExecArguments( javaExecArguments, execArguments.stdin(), execArguments.workingDirectory() ) ); } @@ -225,8 +215,8 @@ public static Result runBinary( final File binary, final ExecArguments execution .map( argument -> '"' + argument + '"' ) .collect( Collectors.joining( " " ) ) ); try { - final List commandWithAllArguments = - Stream.concat( Stream.of( binary.toString() ), executionArgument.arguments().stream() ).toList(); + final List commandWithAllArguments = Stream.concat( Stream.of( binary.toString() ), executionArgument.arguments() + .stream() ).toList(); final Process process = Runtime.getRuntime() .exec( commandWithAllArguments.toArray( new String[0] ), null, executionArgument.workingDirectory() ); if ( executionArgument.stdin().raw().length > 0 ) { diff --git a/docs/pom.xml b/docs/pom.xml index 97e807e2..59db9bb7 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -35,7 +35,7 @@ true true - 1.15.1 + 2.0.0 16.18.0 9.6.0 3.0.0 diff --git a/pom.xml b/pom.xml index e9840489..35eaf671 100644 --- a/pom.xml +++ b/pom.xml @@ -59,8 +59,8 @@ UTF-8 - 17 - 17 + 25 + 25 false false false @@ -69,60 +69,61 @@ 4.38 - 2.5.11 + 3.0.1 0.0.16 - 2.9.2 - 4.8.162 - 1.16.0 - 2.15.0 - 1.10.0 + 3.2.3 + 4.8.184 + 1.20.0 + 2.21.0 + 1.15.0 23.0.1 - 32.1.2-jre + 33.5.0-jre 4.5.14 - 2.15.2 4.10.0 - 9.4.5.0 - 1.4.11 - 1.18.30 + 2.20.1 + 10.0.2.0 + 1.5.23 + 1.18.42 1.0.3 2.6.5 - 5.5.0 - 4.7.5 - 2.0.9 - 0.10.4 + 5.5.1 + 4.7.7 + 2.0.17 + 0.11.0 - 3.24.2 - 5.10.0 - 1.8.0 + 3.27.6 + 6.0.1 + 1.9.3 + 5.21.0 - 2.2.4 - 3.3.0 - 0.2.0 - 3.1.0 - 1.4.1 + 3.2.0 + 3.6.1 + 0.9.0 + 3.6.3 + 1.7.3 2.0.1 9.0.2 2.1.1 - 0.8.9 - 1.8 - 3.2.0 - 3.8.1 - 3.1.1 - 3.0.0 - 3.0.1 - 3.1.1 - 3.5.0 - 3.3.0 - 3.0.1 - 3.3.1 - 3.4.1 - 3.2.1 - 1.2.1 - 3.0.0-M7 - 0.10.1 - 2.17.1 + 0.8.14 + 3.2.0 + 3.5.0 + 3.14.1 + 3.1.4 + 3.5.4 + 3.2.8 + 3.1.4 + 3.12.0 + 3.5.0 + 3.3.1 + 3.4.0 + 3.6.1 + 3.4.0 + 1.5.1 + 3.5.4 + 0.11.3 + 2.20.1 3.1.0 @@ -295,31 +296,31 @@ org.assertj assertj-core ${assertj.version} - test org.junit.jupiter junit-jupiter-api ${junit-jupiter.version} - test org.junit.jupiter junit-jupiter-engine ${junit-jupiter.version} - test org.junit.jupiter junit-jupiter-params ${junit-jupiter.version} - test net.jqwik jqwik ${jqwik.version} - test + + + org.mockito + mockito-core + ${mockito.version} @@ -535,6 +536,8 @@ true false + @{argLine} + -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar -Xshare:off
@@ -574,6 +577,7 @@ ${versions-maven-plugin.version} .*[\.-](?i)(alpha|beta|(rc[0-9]+)|(m\d+)).* + graalvm.version,jena.version From 991cfd653e0785ae16670d2632621108eab54d43 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 13 Feb 2026 05:59:10 +0100 Subject: [PATCH 279/280] Update Jena version to 5.6.0 --- .../cool/rdf/formatter/blanknode/BlankNodeMetadata.java | 2 +- .../blanknode/BlankNodeOrderAwareTurtleParser.java | 9 +++++++-- pom.xml | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java index 83c000bf..d95f8b27 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeMetadata.java @@ -94,6 +94,6 @@ public Set getLabeledBlankNodes() { } public Set getAllBlankNodeLabels() { - return Collections.unmodifiableSet( new HashSet<>( blankNodeLabels.values() ) ); + return Set.copyOf( blankNodeLabels.values() ); } } diff --git a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java index d19589b7..a064e0a4 100644 --- a/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java +++ b/cool-rdf-formatter/src/main/java/cool/rdf/formatter/blanknode/BlankNodeOrderAwareTurtleParser.java @@ -32,12 +32,15 @@ import org.apache.jena.riot.ReaderRIOT; import org.apache.jena.riot.lang.LabelToNode; import org.apache.jena.riot.lang.LangRIOT; +import org.apache.jena.riot.lang.LangTurtle; import org.apache.jena.riot.lang.RiotParsers; import org.apache.jena.riot.system.ParserProfile; import org.apache.jena.riot.system.ParserProfileWrapper; import org.apache.jena.riot.system.StreamRDF; import org.apache.jena.riot.tokens.Token; import org.apache.jena.riot.tokens.TokenType; +import org.apache.jena.riot.tokens.Tokenizer; +import org.apache.jena.riot.tokens.TokenizerText; import org.apache.jena.sparql.util.Context; public class BlankNodeOrderAwareTurtleParser { @@ -87,14 +90,16 @@ public Node create( final Node currentGraph, final Token token ) { @Override public void read( final InputStream in, final String baseURI, final ContentType ct, final StreamRDF output, final Context context ) { - final LangRIOT parser = RiotParsers.createParser( in, Lang.TTL, output, profileWrapper ); + Tokenizer tokenizer = TokenizerText.create().source( in ).errorHandler( profileWrapper.getErrorHandler() ).build(); + LangRIOT parser = new LangTurtle( tokenizer, profileWrapper, output ); parser.parse(); } @Override public void read( final Reader reader, final String baseURI, final ContentType ct, final StreamRDF output, final Context context ) { - final LangRIOT parser = RiotParsers.createParser( reader, Lang.TTL, output, profileWrapper ); + Tokenizer tokenizer = TokenizerText.create().source( reader ).errorHandler( profileWrapper.getErrorHandler() ).build(); + LangRIOT parser = new LangTurtle( tokenizer, profileWrapper, output ); parser.parse(); } }; diff --git a/pom.xml b/pom.xml index 35eaf671..3a983d72 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ 23.0.1 33.5.0-jre 4.5.14 - 4.10.0 + 5.6.0 2.20.1 10.0.2.0 1.5.23 From c41eb5649052ca58e4f3a9e85c781bdad3381824 Mon Sep 17 00:00:00 2001 From: Andreas Textor Date: Fri, 13 Feb 2026 14:58:02 +0100 Subject: [PATCH 280/280] Configure code style --- .development/coolrdf-eclipse-code-style.xml | 333 ++++ ...mportorder => coolrdf-eclipse.importorder} | 0 .development/coolrdf-intellij-code-style.xml | 106 ++ ...ense-header => coolrdf-license-header.txt} | 0 .development/eclipse-code-style.xml | 405 ----- .editorconfig | 6 +- .gitignore | 2 +- pom.xml | 1367 +++++++++-------- 8 files changed, 1134 insertions(+), 1085 deletions(-) create mode 100644 .development/coolrdf-eclipse-code-style.xml rename .development/{eclipse.importorder => coolrdf-eclipse.importorder} (100%) create mode 100644 .development/coolrdf-intellij-code-style.xml rename .development/{license-header => coolrdf-license-header.txt} (100%) delete mode 100644 .development/eclipse-code-style.xml diff --git a/.development/coolrdf-eclipse-code-style.xml b/.development/coolrdf-eclipse-code-style.xml new file mode 100644 index 00000000..b931f82b --- /dev/null +++ b/.development/coolrdf-eclipse-code-style.xml @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.development/eclipse.importorder b/.development/coolrdf-eclipse.importorder similarity index 100% rename from .development/eclipse.importorder rename to .development/coolrdf-eclipse.importorder diff --git a/.development/coolrdf-intellij-code-style.xml b/.development/coolrdf-intellij-code-style.xml new file mode 100644 index 00000000..dcb47ed8 --- /dev/null +++ b/.development/coolrdf-intellij-code-style.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + diff --git a/.development/license-header b/.development/coolrdf-license-header.txt similarity index 100% rename from .development/license-header rename to .development/coolrdf-license-header.txt diff --git a/.development/eclipse-code-style.xml b/.development/eclipse-code-style.xml deleted file mode 100644 index 867fdcbd..00000000 --- a/.development/eclipse-code-style.xml +++ /dev/null @@ -1,405 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.editorconfig b/.editorconfig index d7459b72..aac5a8f3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,11 +7,11 @@ end_of_line = lf [*.java] insert_final_newline = true indent_style = space -indent_size = 4 +indent_size = 3 trim_trailing_whitespace = true -max_line_length = 120 +max_line_length = 140 [build.gradle] indent_style = space -indent_size = 4 +indent_size = 3 diff --git a/.gitignore b/.gitignore index 405bef76..ed5fb1bd 100644 --- a/.gitignore +++ b/.gitignore @@ -18,5 +18,5 @@ docs/package-lock.json **/src/generated/java */lombok.config **/.flattened-pom.xml -*/target +**/target **/src-gen diff --git a/pom.xml b/pom.xml index 3a983d72..20793e54 100644 --- a/pom.xml +++ b/pom.xml @@ -17,715 +17,730 @@ - 4.0.0 + 4.0.0 - cool.rdf - cool-rdf-parent - DEV-SNAPSHOT - pom + cool.rdf + cool-rdf-parent + DEV-SNAPSHOT + pom - Cool RDF - Cool RDF provides APIs and a command line interface to transform, manipulate, - validate and visualize RDF and OWL documents. - - 2019 - https://rdf.cool + Cool RDF + Cool RDF provides APIs and a command line interface to transform, manipulate, + validate and visualize RDF and OWL documents. + + 2019 + https://rdf.cool - - GitHub Issues - https://github.com/cool-rdf/cool-rdf/issues - + + GitHub Issues + https://github.com/cool-rdf/cool-rdf/issues + - - - Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - - + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + - - - Andreas Textor - mail@atextor.de - - + + + Andreas Textor + mail@atextor.de + + - - scm:git:https://github.com/cool-rdf/cool-rdf.git - scm:git:https://github.com/cool-rdf/cool-rdf.git - https://github.com/cool-rdf/cool-rdf/tree/main - + + scm:git:https://github.com/cool-rdf/cool-rdf.git + scm:git:https://github.com/cool-rdf/cool-rdf.git + https://github.com/cool-rdf/cool-rdf/tree/main + - - - UTF-8 - 25 - 25 - false - false - false - false - false - 4.38 + + + UTF-8 + 25 + 25 + false + false + false + false + false + 4.38 - - 3.0.1 - 0.0.16 - 3.2.3 - 4.8.184 - 1.20.0 - 2.21.0 - 1.15.0 - 23.0.1 - 33.5.0-jre - 4.5.14 - 5.6.0 - 2.20.1 - 10.0.2.0 - 1.5.23 - 1.18.42 - 1.0.3 - 2.6.5 - 5.5.1 - 4.7.7 - 2.0.17 - 0.11.0 + + 3.0.1 + 0.0.16 + 3.2.3 + 4.8.184 + 1.20.0 + 2.21.0 + 1.15.0 + 23.0.1 + 33.5.0-jre + 4.5.14 + 5.6.0 + 2.20.1 + 10.0.2.0 + 1.5.23 + 1.18.42 + 1.0.3 + 2.6.5 + 5.5.1 + 4.7.7 + 2.0.17 + 0.11.0 - - 3.27.6 - 6.0.1 - 1.9.3 - 5.21.0 + + 3.27.6 + 6.0.1 + 1.9.3 + 5.21.0 - - 3.2.0 - 3.6.1 - 0.9.0 - 3.6.3 - 1.7.3 - 2.0.1 - 9.0.2 - 2.1.1 - 0.8.14 - 3.2.0 - 3.5.0 - 3.14.1 - 3.1.4 - 3.5.4 - 3.2.8 - 3.1.4 - 3.12.0 - 3.5.0 - 3.3.1 - 3.4.0 - 3.6.1 - 3.4.0 - 1.5.1 - 3.5.4 - 0.11.3 - 2.20.1 - 3.1.0 - + + 3.2.0 + 3.6.1 + 0.9.0 + 3.6.3 + 1.7.3 + 2.0.1 + 9.0.2 + 2.1.1 + 0.8.14 + 3.2.0 + 3.5.0 + 3.14.1 + 3.1.4 + 3.5.4 + 3.2.8 + 3.1.4 + 3.12.0 + 3.5.0 + 3.3.1 + 3.4.0 + 3.6.1 + 3.4.0 + 1.5.1 + 3.5.4 + 0.11.3 + 2.20.1 + 3.1.0 + - - cool-rdf-core - cool-rdf-diagram-owl - cool-rdf-infer - cool-rdf-formatter - cool-rdf-write - cool-rdf-cli - docs - + + cool-rdf-core + cool-rdf-diagram-owl + cool-rdf-infer + cool-rdf-formatter + cool-rdf-write + cool-rdf-cli + docs + - - - - - cool.rdf - cool-rdf-core - ${project.version} - - - cool.rdf - cool-rdf-diagram-owl - ${project.version} - - - cool.rdf - cool-rdf-infer - ${project.version} - - - cool.rdf - cool-rdf-formatter - ${project.version} - - - cool.rdf - cool-rdf-write - ${project.version} - - - cool.rdf - cool-rdf-cli - ${project.version} - + + + + + cool.rdf + cool-rdf-core + ${project.version} + + + cool.rdf + cool-rdf-diagram-owl + ${project.version} + + + cool.rdf + cool-rdf-infer + ${project.version} + + + cool.rdf + cool-rdf-formatter + ${project.version} + + + cool.rdf + cool-rdf-write + ${project.version} + + + cool.rdf + cool-rdf-cli + ${project.version} + - - - org.asciidoctor - asciidoctorj - ${asciidoctorj.version} - - - com.github.ben-manes.caffeine - caffeine - ${caffeine.version} - - - io.github.classgraph - classgraph - ${classgraph.version} - - - commons-codec - commons-codec - ${commons-codec.version} - - - commons-io - commons-io - ${commons-io.version} - - - org.apache.commons - commons-text - ${commons-text.version} - - - com.google.guava - guava - ${guava.version} - - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} - - - org.apache.jena - jena - ${jena.version} - pom - - - org.apache.jena - jena-arq - ${jena.version} - - - org.apache.jena - jena-core - ${jena.version} - - - org.apache.jena - apache-jena-libs - ${jena.version} - pom - - - org.jruby - jruby - ${jruby.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - org.projectlombok - lombok - ${lombok.version} - provided - - - com.github.galigator.openllet - openllet-jena - ${openllet.version} - - - net.sourceforge.owlapi - owlapi-distribution - ${owlapi.version} - - - info.picocli - picocli - ${picocli.version} - - - info.picocli - picocli-codegen - ${picocli.version} - - - org.slf4j - slf4j-api - ${slf4j-api.version} - - - org.graalvm.nativeimage - svm - ${graalvm.version} - - - io.vavr - vavr - ${vavr.version} - + + + org.asciidoctor + asciidoctorj + ${asciidoctorj.version} + + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} + + + io.github.classgraph + classgraph + ${classgraph.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-text + ${commons-text.version} + + + com.google.guava + guava + ${guava.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + + + org.apache.jena + jena + ${jena.version} + pom + + + org.apache.jena + jena-arq + ${jena.version} + + + org.apache.jena + jena-core + ${jena.version} + + + org.apache.jena + apache-jena-libs + ${jena.version} + pom + + + org.jruby + jruby + ${jruby.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + com.github.galigator.openllet + openllet-jena + ${openllet.version} + + + net.sourceforge.owlapi + owlapi-distribution + ${owlapi.version} + + + info.picocli + picocli + ${picocli.version} + + + info.picocli + picocli-codegen + ${picocli.version} + + + org.slf4j + slf4j-api + ${slf4j-api.version} + + + org.graalvm.nativeimage + svm + ${graalvm.version} + + + io.vavr + vavr + ${vavr.version} + - - - org.assertj - assertj-core - ${assertj.version} - - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.jupiter - junit-jupiter-params - ${junit-jupiter.version} - - - net.jqwik - jqwik - ${jqwik.version} - - - org.mockito - mockito-core - ${mockito.version} - - - + + + org.assertj + assertj-core + ${assertj.version} + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter.version} + + + net.jqwik + jqwik + ${jqwik.version} + + + org.mockito + mockito-core + ${mockito.version} + + + - - - - - org.asciidoctor - asciidoctor-maven-plugin - ${asciidoctor-maven-plugin.version} - - - org.sonatype.central - central-publishing-maven-plugin - ${central-publishing-maven-plugin.version} - - - org.codehaus.mojo - build-helper-maven-plugin - ${build-helper-maven-plugin.version} - - - org.codehaus.mojo - exec-maven-plugin - ${exec-maven-plugin.version} - - - org.codehaus.mojo - flatten-maven-plugin - ${flatten-maven-plugin.version} - - - de.saumya.mojo - gem-maven-plugin - ${gem-maven-plugin.version} - - - io.github.git-commit-id - git-commit-id-maven-plugin - ${git-commit-id-maven-plugin.version} - - - org.codehaus.gmaven - groovy-maven-plugin - ${groovy-maven-plugin.version} - - - org.jacoco - jacoco-maven-plugin - ${jacoco-maven-plugin.version} - - - org.apache.maven.plugins - maven-antrun-plugin - ${maven-antrun-plugin.version} - - - org.apache.maven.plugins - maven-clean-plugin - ${maven-clean-plugin.version} - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - - org.apache.maven.plugins - maven-deploy-plugin - ${maven-deploy-plugin.version} - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven-gpg-plugin.version} - - - org.apache.maven.plugins - maven-install-plugin - ${maven-install-plugin.version} - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven-javadoc-plugin.version} - - - org.apache.maven.plugins - maven-jar-plugin - ${maven-jar-plugin.version} - - - org.apache.maven.plugins - maven-release-plugin - ${maven-release-plugin.version} - - - org.apache.maven.plugins - maven-resources-plugin - ${maven-resources-plugin.version} - - - org.apache.maven.plugins - maven-shade-plugin - ${maven-shade-plugin.version} - - - org.apache.maven.plugins - maven-source-plugin - ${maven-source-plugin.version} - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.graalvm.buildtools - native-maven-plugin - ${native-maven-plugin.version} - - - com.diffplug.spotless - spotless-maven-plugin - ${spotless-maven-plugin.version} - - - org.codehaus.mojo - versions-maven-plugin - ${versions-maven-plugin.version} - - - + + + + + org.mockito + mockito-core + compile + + - + + + - org.jacoco - jacoco-maven-plugin - ${jacoco-maven-plugin.version} - - - default-prepare-agent - - prepare-agent - - - ${project.build.directory}/jacoco.exec - - - - create-report - - report - - - + org.asciidoctor + asciidoctor-maven-plugin + ${asciidoctor-maven-plugin.version} - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - org.projectlombok - lombok - ${lombok.version} - - - + org.sonatype.central + central-publishing-maven-plugin + ${central-publishing-maven-plugin.version} - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - me.fabriciorby - maven-surefire-junit5-tree-reporter - ${maven-surefire-junit5-tree-reporter.version} - - - - ${maven.surefire.skip} - ${project.build.directory}/surefire-reports - - **/*Tests.java - **/*Test.java - - plain - - true - - - ASCII - true - true - true - true - false - true - true - false - - @{argLine} - -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar -Xshare:off - + org.codehaus.mojo + build-helper-maven-plugin + ${build-helper-maven-plugin.version} - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - ${maven.failsafe.skip} - + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} - - org.apache.maven.plugins - maven-release-plugin - ${maven-release-plugin.version} - - - true - clean verify - [Release] - true - @{prefix} reset version to snapshot - - @{prefix} release @{releaseLabel} - v@{project.version} - true - DEV-SNAPSHOT - - prepare-release,maven-central - + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} - - org.codehaus.mojo - versions-maven-plugin - ${versions-maven-plugin.version} - - .*[\.-](?i)(alpha|beta|(rc[0-9]+)|(m\d+)).* - graalvm.version,jena.version - + de.saumya.mojo + gem-maven-plugin + ${gem-maven-plugin.version} + + + io.github.git-commit-id + git-commit-id-maven-plugin + ${git-commit-id-maven-plugin.version} + + + org.codehaus.gmaven + groovy-maven-plugin + ${groovy-maven-plugin.version} + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + org.apache.maven.plugins + maven-antrun-plugin + ${maven-antrun-plugin.version} + + + org.apache.maven.plugins + maven-clean-plugin + ${maven-clean-plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + + org.apache.maven.plugins + maven-install-plugin + ${maven-install-plugin.version} + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} - - com.diffplug.spotless - spotless-maven-plugin - - - - - - .gitattributes - .gitignore - - - - - - - - - src/main/java/**/*.java - - - ${eclipse-code-formatter.version} - ${maven.multiModuleProjectDirectory}/.development/eclipse-code-style.xml - - - ${maven.multiModuleProjectDirectory}/.development/license-header - - - - - + org.apache.maven.plugins + maven-release-plugin + ${maven-release-plugin.version} - - + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.graalvm.buildtools + native-maven-plugin + ${native-maven-plugin.version} + + + com.diffplug.spotless + spotless-maven-plugin + ${spotless-maven-plugin.version} + + + org.codehaus.mojo + versions-maven-plugin + ${versions-maven-plugin.version} + + + - - - - prepare-release - - - - org.codehaus.mojo - flatten-maven-plugin - ${flatten-maven-plugin.version} - - - ossrh - - - - flatten - process-resources - - flatten - - - - clean-flatten - clean - - clean - - - - + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + default-prepare-agent + + prepare-agent + + + ${project.build.directory}/jacoco.exec + + + + create-report + + report + + + + - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven-javadoc-plugin.version} - - - attach-javadocs - - jar - - - - - ${maven.compiler.source} - - + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + org.projectlombok + lombok + ${lombok.version} + + + + - - org.apache.maven.plugins - maven-source-plugin - ${maven-source-plugin.version} - - - attach-sources - - jar-no-fork - - - - - - - + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + me.fabriciorby + maven-surefire-junit5-tree-reporter + ${maven-surefire-junit5-tree-reporter.version} + + + + ${maven.surefire.skip} + ${project.build.directory}/surefire-reports + + **/*Tests.java + **/*Test.java + + plain + + true + + + ASCII + true + true + true + true + false + true + true + false + + @{argLine} + -javaagent:${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar -Xshare:off + + + - - - release - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven-gpg-plugin.version} - - - sign-artifacts - verify - - sign - - - - - - --pinentry-mode - loopback - - - + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + ${maven.failsafe.skip} + + - - org.sonatype.central - central-publishing-maven-plugin - ${central-publishing-maven-plugin.version} - true - - central - true - all - false - - docs - - - - - - - + + org.apache.maven.plugins + maven-release-plugin + ${maven-release-plugin.version} + + + true + clean verify + [Release] + true + @{prefix} reset version to snapshot + + @{prefix} release @{releaseLabel} + v@{project.version} + true + DEV-SNAPSHOT + + prepare-release,maven-central + + + + + org.codehaus.mojo + versions-maven-plugin + ${versions-maven-plugin.version} + + .*[\.-](?i)(alpha|beta|(rc[0-9]+)|(m\d+)).* + graalvm.version,jena.version + + + + + com.diffplug.spotless + spotless-maven-plugin + + + + + + .gitattributes + .gitignore + + + + + + + + + src/main/java/**/*.java + src/test/java/**/*.java + + + ${eclipse-code-formatter.version} + ${maven.multiModuleProjectDirectory}/.development/coolrdf-eclipse-code-style.xml + + + ${maven.multiModuleProjectDirectory}/.development/coolrdf-eclipse.importorder + + + ${maven.multiModuleProjectDirectory}/.development/coolrdf-license-header.txt + + + + + + +
+
+ + + + + prepare-release + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + + ossrh + + + + flatten + process-resources + + flatten + + + + clean-flatten + clean + + clean + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + attach-javadocs + + jar + + + + + ${maven.compiler.source} + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + attach-sources + + jar-no-fork + + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg-plugin.version} + + + sign-artifacts + verify + + sign + + + + + + --pinentry-mode + loopback + + + + + + org.sonatype.central + central-publishing-maven-plugin + ${central-publishing-maven-plugin.version} + true + + central + true + all + false + + docs + + + + + + +