From 79c0bdc75b54d93b6d4b6a76b41e73b910a6b54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as?= Date: Thu, 4 Apr 2019 14:09:19 +0200 Subject: [PATCH 1/5] Remove sesame occurences --- docs/webService.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/webService.md b/docs/webService.md index 04dd9c7..8ae9517 100644 --- a/docs/webService.md +++ b/docs/webService.md @@ -37,7 +37,7 @@ A few services returns more or less the same rdf resource definition JSON format ![rdf-resource-definition-dto](img/rdfResourceDefinitionDTO.png) ### Property DAO -To manipulate the properties extracted from a semantic triplestore, we use the PropertyDAOSesame class. +To manipulate the properties extracted from a semantic triplestore, we use the PropertyDAO class. ## How to create new services ? You can base your new service on the Provenance and Radiometric Target services. From 12d927407715a8b3f443cf990606f4a3db46afad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as?= Date: Thu, 4 Apr 2019 14:10:33 +0200 Subject: [PATCH 2/5] Replace phis2ws package by opensilex and remove phis package --- docs/webService.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/webService.md b/docs/webService.md index 8ae9517..d1d5e2c 100644 --- a/docs/webService.md +++ b/docs/webService.md @@ -41,11 +41,11 @@ To manipulate the properties extracted from a semantic triplestore, we use the P ## How to create new services ? You can base your new service on the Provenance and Radiometric Target services. -1. Create the service class in the resources package (e.g. phis2ws.service.resources.ProvenanceResourceService). -2. Create the DTO (e.g. phis2ws.service.resources.dto.provenance.ProvenanceDTO). -3. Create the model (e.g. phis2ws.service.view.model.phis.provenance.Provenance). -4. Create the DAO if needed (e.g. phis2ws.service.dao.mongo.ProvenanceDAOMongo). -5. Create the ResponseForm (e.g. phis2ws.service.view.brapi.form.ResponseFormProvenance). +1. Create the service class in the resources package (e.g. opensilex.service.resources.ProvenanceResourceService). +2. Create the DTO (e.g. opensilex.service.resources.dto.provenance.ProvenanceDTO). +3. Create the model (e.g. opensilex.service.view.model.provenance.Provenance). +4. Create the DAO if needed (e.g. opensilex.service.dao.mongo.ProvenanceDAOMongo). +5. Create the ResponseForm (e.g. opensilex.service.view.brapi.form.ResponseFormProvenance). ## Java Bean Validation (JSR 380) From 1b1b3e040c42210f894153f2f1e5846f13791ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as?= Date: Thu, 4 Apr 2019 14:12:34 +0200 Subject: [PATCH 3/5] Replace rdf by RDF when possible --- docs/webService.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/webService.md b/docs/webService.md index d1d5e2c..41eef8f 100644 --- a/docs/webService.md +++ b/docs/webService.md @@ -23,16 +23,16 @@ The models are used to represents the concepts which are gonna be manipulated in ![dao-dto-model](img/global_dao_dto_model.png) -## Rdf Resource Definition +## RDF Resource Definition To represents and manipulate the triplestore resources (instances or concepts), we have created models, DAO and DTO. -### Rdf Resource Definition model +### RDF Resource Definition model To manipulate a resource (instance or concept), we extends the RdfResourceDefinition model, such as the following example. ![rdf-resource-definition-model](img/rdfResourceDefinition.png) -### Rdf Resource Definiton DTO -A few services returns more or less the same rdf resource definition JSON format. We have created a few DTO which are extended. In the following example, the RadiometricTargetDTO extends the RdfResourceDefinitionDTO and the RadiometricTargetPostDTO extends the RdfResourceDefinitionPostDTO. We have created a specific package which will contain all the DTO of the radiometric targets. +### RDF Resource Definiton DTO +A few services returns more or less the same RDF resource definition JSON format. We have created a few DTO which are extended. In the following example, the RadiometricTargetDTO extends the RdfResourceDefinitionDTO and the RadiometricTargetPostDTO extends the RdfResourceDefinitionPostDTO. We have created a specific package which will contain all the DTO of the radiometric targets. ![rdf-resource-definition-dto](img/rdfResourceDefinitionDTO.png) From 73ea34339a1d3126ee72a50b3de1db2d533612ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as?= Date: Thu, 4 Apr 2019 15:15:29 +0200 Subject: [PATCH 4/5] Make architecture schema more explicit --- docs/img/global_dao_dto_model.png | Bin 39561 -> 0 bytes docs/img/web_service_architecture.png | Bin 0 -> 24409 bytes docs/webService.md | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 docs/img/global_dao_dto_model.png create mode 100644 docs/img/web_service_architecture.png diff --git a/docs/img/global_dao_dto_model.png b/docs/img/global_dao_dto_model.png deleted file mode 100644 index 06063a369c5eff798d994752a584c0458e58bacb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39561 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
  • jTN=>-Q0_)Q}KP63NU?1{Q@^ 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 diff --git a/docs/img/web_service_architecture.png b/docs/img/web_service_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..400c3c469b6f82e1f6071cffddc842d772628f85 GIT binary patch literal 24409 zcmb5Wby$?)*Dh+(ok}-~bb|~i-5p9wO3ctb2r4ZtB3)9_J#y@YG3E8yc$;oP`!17Ar|R{O?{+Zs1++*HK6 z1>V8z(Vn|;!;C>m_NlJ-EUHCH)!j_`>Z-nqJC*fO)8gqpeV5~YksqJ#&xe!H;>%a5 z^Re0TGAi?F=~_GpQ^&ijMG~HDfrDf5KrxpABVH*t>jnPZI9VLk2M@qISy@?0Z?C_0 zA01r28s7E$m7W|LKseZbt{1y}DR#WzwhP(x7+ECr>bYkb$+v;}{YC3VBp-Nz6!`lN z0s`Lt|9Xkcxc*3FCF=h5hutNPeE(cr_yq(6ynOl6(lW=el$)DdUF04;J$*!v_Pb;EhV(RMZ5)%_QH#XjN zuk7tPv&En8E#D4s5xT&u>l~q=px{XODt{ZX7{d^B5Ec;;ak7|`ljFTwTFQ0zEh=Ha zTAG^-=hQF5^62QuW$w$Dr*~XjU0wbC{b4Yem)G&m&LHCD_5B^#?eWUOTwGl2?d`3s z?qteTRL$&kb=_I1ZESpJn4XbgYHHfLqQn&TgIW7osXn+bmoM4bjGVD;7dF_N;ZGOl z=BCkqFSJlN_4D!L#|g@JGY160E%%~@MMMY*3C*Uq>AFxT)XdC%{&(9$gM(|XViM%$ z>8YtkW@fzvF!=Qj`tTT=nK{8=Y8o1Z1Oyl@$c2U0`g(7bL?1UdH+T1%sw!=cgsK_N z-v$rJPL3}w=KiieNu&>4wJdOd336{?c6RpV?~G`Vx%Bk(A zZ{K!sa44&MMFh^0nwnacme}@hbg71(eFbsCo%l28TS(J~@$qq}a8rH#fBvyoi<6?D zpui;eShlRZoSmIrCGY*e$e`_7UN#p_^^lOj1y=-@C*)wN{kPr&eh8!mf!Of&=BA*e zq@*+^Pit!1wZv$ z*xxhugTDB;)B;{!-q<0V#E&0o$Til`XoN90CC=S{fiI3VAuAI~7SZk7@(as{2864( zX`yaoL&Lv>$ghTKNO2_Kw0U`X(Xta-2Lxn(X1+zLW&iKWm@{-cC{$E*^oDCgR1`iT z;zG&M$*B&3ke8PaGS9Jsi-)}aL&)qGb6Q;8CzkyVjv-R1=Jip=Blf!8yXreFE1-AEA4B2eSNp# zLFZsgaypV#L)vym$>FCRV7+ zaq36c|0qGZ*0A)C_XGm6`l0)trRvnQ=^)tJ-@kuPPd_s=TkPw@+Nf)7_4o6OByO#Q zYn4xdvjRr~eiEOAD&^w*;$quo0tiYS3a~~KJNO$ADj;_!CnrJJ8gow}k<@FuOG{Zl zQ_hy1!*+&;)$_Eq0_E@sM>^5YtqPIKV6E!Uukof1#aiFmD*szwUtc-zebM9nHmGm} zFG&86%-TP6*(a_{O-z;x!Ey~tKNST_->mz&wROEy6cGmp2S!Flo12?F_w)Yy=I6bP zFLu|~tl)6!Nw6lF^N`R`IJI+qTwEO3yR9udeJ(Dp($Z3xqvJ0TQAtV3m?y)tGmwo6jy;HLZ*Nh$w_u4iDM=Swsu~(@SW-875HCUYJ&f>Kotv9GJUUuGIQ3p0 z9wuN5+KY;b=^coZ`sn23B-MmsOou=q5_JOu1Ge<+6%`euQ%gHLJ8s6JZ+}j8fyKZ^ zM6LOD-&$0LO?Q*h4-F5akB>(N2N{g^e-{=$OxppuJpc#vb;+!j6%u!O=}|K-(ukm2gG-x;VmkpX z5NomgynyoZ^4^}FXZ#WpX(O9@gag8rsO%7sf)_(p{1*cq`kR^@2{lj88z#l>3(JU$ zxtp2Mzp->O%)X0Fc3~KkEqSza4`-o+JKTOI32d5j9*Nh0Tmwk;4y(-vlqxF? zBVv`BV{FJ(=?+7L)p`B){WrLOv@DP+p@Yde2}i!KTwM4(jrr!vxfT}|Y{X3K$ru9+O-%_9q3zuYPZ4hw5X+!cf!rPi z(WaZk?xAD8JZ1m@?;#n^7qt7~Yh$(bh&FD!jSuAT6%+g4aU*Is7LAl z^|Ke9$Dc0AREbaehh*Fr)dv)*P#1^VR!lfw-;rLYq@?5yQiaAE3N4w8e_lQ{Zt{wU zhlg0UV>wj)#+3@a76AuR#l2Zm22v~3MMXTrkX4DQedxZHHp#-L_6f6+4*^+J202ab zDE=q;i?`rc6JvWJF|lx0rQMD&4i2QlxM!)|%mSzyw$qe3qa@v~E}}^^1zj=vtj?uS zjYeS!iAaPEe{y|>h!%n}g$rl+;_&c83r_GY;+5Xc|H?!YkbA1asY9Cw-4=YNWpsGn z+H=}!_!}f4K{b`-XXbrlD=tZsd3DCz1%xK$Q~O-e8QcpxW+u9# z2BR?uUD`c45mgcNH+_WcBoJa(u#jk*Mo%CUI}0^+rkI-6Ri_hiu>%JbX&@Wb{}Un%$j@ zz&!xGbUI`dEB?kQZO@*AHQdWAIp0gI@ZnASkUA;)1EC|t%=QDU4@Qc?z*qD&43`uZf*IyL;m zLqlpuaO=bxFAghxyFhOn;pk!FRJ!2c5@kUqmc6cS*JOaIL4#r}+#g?gSQtY;=}-M9 z@BY$NyDHeo|GiNBuLa~n6tEA#XOI~#UoAk<{SUSS>ipknd`%pNaRKCml>R?{ACvR< z(5RmFzyc%CZqrdMv zffdkz6*T*&TpYT?ot=sL&(EgXE>TVa=T28>CyQND0J05O7$7{^nxIfhNlL0i z0~M;CPt8Yw7zIoLnemqbZb>2m1(AqjHj#xmD~d#4-ZI^|E$<&3Nf{~I1;@j>;s3x0r|cF_cvn2FG~8GteJ?GlOm$% z0QK`{YDR|qM9uczUhEA}NULW!9rjC`@MW?;?MEIC1#Tl6Pm(v0{F<;LFEHY+md(sMSDjOxu{7n>#qD6oq;-1_0z& zTwYmW@(eESUjXHQ5{GC6P|% z)e=D%^qVz5tu@3)gkA&_jq)Q19SZ_&`0pR8U)fYY-{B%Vs?=Y9E6(KG>omx}@_VVGsnE?n{6Dr)dCAv~gO|3A1d&ww!j}rmWEh#8?>E|br9cgPJnMsH!U}{OK zZ=uZ>6%@=Rm7gC&mY0+SF{`Vp?mgC;GJZfN`spwC0m*`d^L~C-sH=V6P=m^T?ZOIu zvMPs(jEGpt_2vA6bZtnpw_{uYs+McP-^q!G#>L8NO$Jv|ETslE@;B3)9gs2wU{_Ow zUsKc4cE?Z12*cn&REDEms-_pFSxazM7eF)(jf?;ul9`cVFCW_^-}FQuNX6c4n3Gd4 zBC+2}IAy>8W+n{2@n?2n{N)Z`k3?{PzY@DKqD8#|VrSe@6C|#k3)=^%5W zQ){c_(X<+JVSC%YvBv4eizn=ZjG*u;=V>>4+SxtSil;uic(;m?+57~V;nRlLta@VE z_%mGy(K2#qY;Fj0A#C>7FUL=Vgn2+XM&$7xjxD*}m5Q)dk*uq#8k<1pI_@(94J)ly z<`>-=e1nIZTTowRPQ}vPoN=ejkv=;<^m+qb)GYytoJJc~wX~EHG|WIf8*jevZ9CEb z;qgceWMEOd90F+E(Jtk@x09e`Fa-c1vK<fIT|aSw7(Nvx10$0APv(r^-WhQ z9UYxK?eJK=1L~OejGgH%vJcF3G&EqdbtpCk0ojU#?T)|j5D*Z^7U8A~Y3~*= zT{7~fqs9ZZYHLrxF1csh$j}hS#4#o&Cazl6e0gId{|>=OYEn}B)%U5X8BUsDdO%A# zA5ug-n4g`cqQ=Z*b|(1phU^wH=uIM0r&M1C8_=ig!$m+2)M2}mGqbbe5J*%aCnqO^ z=T`WX_^BRH#n%#bH*2>XRxUOJ70zfut*ltQc=5v9yS~X(?_aiG5S(4kqEo6{TIR>c z1DDm*)q(GF4B+kfc(J?ffO-=Xx_R0@N8-l+E^>|Lf3f=- zu@;{$njtfQmcGXCmr<~hk%WIQu0_^?oAoumrZZieOxJJxzh59)qLL%v@`T>k}!LVQkyAdo8_u-u0N`H+u`4998bW>ZTGEiLW(*vUZDlBcSwsg!#;u8pRl(!w#Sc!Y%P$}u1+dGWf6P0JU1(LiSNRToeqTqJ2&&EfY<&z!|G0kf|= zd|g^z?xv+^+Pt^4^cpV6&;MI2`ovh|ABJ2539T}4M^Gr%HjQ#aBco1+3cGoWX>py-P?+Mdb z05IJ$)MXfFKtQ$>Z5Jq&?~sze#R@74yel34xQB5B$hgD9ApAWs3Xa$(a3m1G36vqc zt8U|k81(BBV#pIejs#^a9Nfq$fcF5DuCDr(x9^0#bAI`}d$*xM3lfPvPfoHr8rx16kjm4nlJWWg4z3U}a zvNBkZpT8oo`5>J1e-7|vWkZ7!q6J`!ePDPvws7oNKUzBCa(>=K_jQ2Y1*ytym8uyi zus6Pcrx4aGpJJuCD1HI_16Fwh0|V$F;ltrS18DFC&?FY284@ZP@&t>NQdS|hVtNFa zWx6GLoD?(9u1t-MU#JA-E1Pp8G#_-mJXb=l3QninuGP$>yKT%?^2w0}%p}!oW7E8G zv#94`?}H8-ou-Zl6_LjL5pUb|M<^iPZ(x*c@X3>`fO{gA`x_P{t|b7%58#$puid)l%j z%70`dk41IM$=X|m@U!JU9aw$gBKe6aaiA~^i}Fhy$)zqw!Y{)bq)f&NC!5`HK<*+N5H4^jt;MjB`=``R&k+y+Er2+DXj)uEOP4x62(#eQPKd=o1;0Znd=^D*Z{ut& z_kyxB&MaKpGRp2{Z;uo6^fhnBw2dxPSY5Zmhw;y0>IntL9bdmHf0Fvz*QdDB_^TBv z73w`dj$W~O3rw!(P|{^%xL*bidC|R<#UN_ zWGaEmH&frX6rR;5Sol|IaH}{!%w^%W{vanL_tXVD$>IU;YOC`k$4_k^^A$ne?ZUD0 z^J&wS{JL$a;;7WIo@C8_U_&a;uXuW3lZdc-_5ypa{!oxip3Tv?m|dTEj4k9Z)49gx zsql%PN5FEZ=?pI}esqXcr}#+SIV>Mh@V4f_hT$1tY8sU-P4X(D>W}05gB-Itd^%o? zDMbFfe+rNaA|g_NaIvrdIAk+krC`}iu?>Y1#NtP8o@4?@>)zs9q z9HgZ*+-7%(r~=n(LD-wTw6R(7T?j(eawL2}x$MsN0{8VAjlmz{(eBmNuk8h7=m~Uh z^uDY1Oitdmvb57wsh4Hf6b7Db51PdpyC69wMf-6BJi4yHpDtUi4*jla#-0&qIp9I6 z3A+E>-8F#apCuPv@DmwC{$`$l<9KM;S;Oxr%67Lr0%<2YXBg-XWzI^=K+x0BuM8d&6|rv(hV^>kH_DdG_|pNo9==0OD_P9#qHV-E7c`GuM=fBBV(R zr=QlamFkUISTHS2H9Wf84aBdAh)B_>ZncE^`v7d6d8h|A=klQ@WYQA2z|N9)28i`6 zLhq6gyrU@7ogyjwK-+13Yq+R!Ngq+rF;MZ?nSncVV68-y6pfz^03q8;F(bOHJ$$L4OMB$(7Z7xrV~?vMWzx0vICbyEz2K^pQ<2@e@kR{1fCnD%IH z&8x(VN-9`y+xw|4hjvG(U{vad&qLnu_jI1RO4G~Bj0FX}VxP%`(=u=-v2;uz?u^+E z!OA$3l(L=WM1;$;9(Fq&(XwQZs}NDB`B%@0OTx70LVDtW8<&gIH*w|p?$#}&kc;AT2x+_X^CL|)#YXkN3^P5wqdR;qP^^B97i;I;lYH1O8 ze-^j#n<*V=-dIwnkiLDjnjL5f=-6{=b@F+wB$^L0y#)m?h##gCrm}9+duV?D#1HCk z_|rfas*8}?&x9|#PlLu3{0lH;zH=)U$bVEiY;WhsE*O1Hzhx&S>Q;gqW$AUP&ynB` zvlBHJ#v=dnNiUKZs~9w4NP8{Jjd>y`iBE$DS=p_khsZihhe3bmuS$l(ojw9DW%gw_BS|&hD*sM|0(`$I`m+2Rq8>b3lVqyYu8a|UoAIfI? z&FNN}`j>Bm?+-C3vUQ- zzM@GiWdP!RvJEdZ>pD6T+IZKwPYF{CEmz6}?&nIjAdm~1NN-V>f9x%TZzF2j^e^9n ziLcc3u)ixv`_8B-&ceyJ=dCl1kqQ+`6H@n?V94nHC5b3_1>|lqiAV3ONnnthNqD>j z*bFYp_uOQ%qz&SpK3#XdA|P!=e<7pC{WA*ei-i_QxriRtlt1IlhiTk( z>Z7^r`Up-osIv{Q$Vv~;bIiPMSZZ*Pq^r} z^)9(^KG2s7zwuwCCFvIel8{%sWyl9aI7Uj$GXy2&xBkHzaEFtVdj3w1jv-utpI5Z> z_xCr+$C(3t8bbN~lUcH={Ls#?=kdiYx?IRZzmB$jya8EaoM~ zQO_Tk6KFA*7TY)%okeoNEG(qCwuhOgX_qZgXtZa?UCUoi@OxHJILBbb2(O8LfoaR% zjsL4M4osmMLJg%|Ke_edsVQ^kh1hbnf}tH_H3mAGHE7G)xkWUn5fh%8S4G)$(x-fH zSwZ-LPSyT;J=+uj5_*LKte$2{q|UN&p{{+S@VrV+AHvT>K z5$Hkhbg;tjPykdI7E5Eg2ksM?K8liLBXZyE-K{^Cl$ZZB`eVZ%ac+cQ?Vt{R zc{|&;66x$LS}~fke4Ldgd2)`;EK@4}KEu-QJ!mYooJTyIoVMX#PdggAZ8su88~so5 zPbzx)n9^St7sfe{q&~eEL2MfQ<&8Z_(Fn-&{QRW5)eMwEBqc3v(28H}rF!QWFiW1c zP2YQin^VW~bxpT9l%Q&TZjNTTm$@R#eJ5fs+W{zBn&?! zJ4AtxAn$MzI?S@`yu6guQn({&0hIT(>)1Gk zRu!53Uwg|@p&zwcWd5hQT&Zsvh`dHqAjA)bwi%G5p`oFqq@*Cx6O`A9nN`{_HJ1|- z60)-yVGKKrn5yMR}}3-}X9TEErFc~)!P|9n=` za|s`C$ay64QQ`n-tI^P2A?N2`IVCg$+(}TDbAu!*=YjZhpK$!Qa$w*-2bSkG$^iG; z($W${FpzFZi$HP%UV}`1mt$HET899>fl*=Uoy6VR)Yf(-RyOhXY_1(?{oeV}|6l#& zk@<2^Y#XQ1zfUg|ELDv_n;iyMf6?>}O#((Tn0+2SdX%TFG?{*4CY&ml1bTl1#1Gwz zNVfw3vh7V6mg<-4YfVaLzed`<-LR+>m6B?!txZT8-E{-mX##~0gV~OGuTiH@uw9Qo z|A*!>Hn=}zm8=i+9(!4>{2cA=-&xw7 ztrF5p9v&aNxl7i7j)Um0g@py&ru4tnasRO`&>b!7)bH+MaCP>B=7~!c=-O%*3VwfL zNb%$6&vT-0Mq6^)8^2;A2--l9P2tWS+x431pvg-QWb$hi9Y z_kV?Jsr0dLY;Ja*Y=QX5NZj>5ZX(?7M2?TUWe&BT4mnxC&8~pcepKqTA4ur~gMq<_ zFq^;Gl)-4dwYy7CM|U~w)p~H=c6DBBh{BXQc>^0sG9Y^kcZ^wnwckw{aHtSa)7&h< z%RAa?kaNw879y&us#f;vOy6sKB=tK-F6y@xIQbu>nw`&1`JWX8oL#y}Jyzo1sD<); zf7}-SH*VDN;+7W#t?!jZ{`T;@Y>qi*;(V`)5ira@2$k?wM&P$D6d*}U+q>qUe%jO zlCF`dzW@esHIgpFfICqrXZZVfFtT-2eaEPL3P>7YsqiP`UB29`Mu{o$J8=>UNBe+5 zlv~L7P0(K$92p5{W%B|{2Gb}s-NP@DZttyjXu$p;1$eCBz(@JrOes+D;v?vX9Qn?B zeFIE29rPWc@C~;a(^7qS>8xHF;1k!I;N&zSGWI|Jo($XF*suYno2~7Slamv2o*R=g zC!=b|$m_wNP3OULU$E*K=^)r7BFqr+SXR?(_A!Jl<)K!AXsG>R2az?530+455U_XUIBsX zni??OCEZuw3zSpucF^qbW@QT~zwX;BE1xXOG4W~d-Sd{k&eYi?P$~uM9X6*qK(xT$ zzKGksMnWE*k)a{-h;A?zq{?=%+=+SV%6O8zv2Xb7+2}+`JNleB$eHfVTGtgFF#oBU zrE%_DgK-dGDY`EvrlxvbzOnr8lW`@fP{QEt-CZ!BfZBtP3@y<~9ZIB&w}~JDFv6LAO#-djO)508X9v2#}* z)cf)1_hF2|xyvja^$c6Q6n$p?)j;j}4q!t=&p&4GI9Qe`iVT#jjuAePou;Wi}V6t$H%yZGJkp zHdgh~=VG`IPj|t?=?=t{Kx7)5V#Y<$*MJ{_z)n zel$pCYvzQXpURSRksz}B9u)3_{y2AHrw;LVFmVNvgVL7PiwDU(LkqlzquozlubcOt zCfDg~dRfCoNn;d@zjw1U`_@!c?EU5&RW=@dtlzByB+qD;Y%;}p6>nS#kw9+veub*Q?tAdQy6UmlZEPza%e1&9MRFy&I#IuABJq=+N87F z+febXBerm>dp|aR|8|{{WBuxP)jU*qa9#;%y$O0TCuzzm^0p>lZcFjZBpo^i5K z{jMv)x~mwUF)RI08eOFV|pa4B$#8LN7f+e;R|!g$@fWA z$HaffZK@4P!r)z^m5Wg>3j87x5;Q4%Vo?>q@>Ebu{Tlo-V=aU-Mj>ny^9rE7SJVnO zO>kYDhH6Q04iHYtyWV1*I=xLC2{f?w9>2~?d}a0qElX2rnKoW&n!9aE0SMt*2wAA} zERv3+Uo5vg!m`r3RG(RIJ(MkbSsIIXxiyW~w>MO%kgLr|P7yCrCTW_hiKt37j{ZWW zBdWijMU*1byzkCbM8j`6l_Z+CmW*M!Ubgh*unGv8)nC*cv7D6_@(~j$lPI*u{)6;% zUL2FJzcleaX4tb|-p$Et^?D4AF);VNOK0N@Ae~^l@tKRc!p%p@T1w`o^-qm3-)=rM zTK>c8<^2)or^YnhOeeFiggb$iFkocIKJHNXZZEnoXx4!2{jV;)Mnw##H~i97V|${Y zBRJ5*qT#EiSTv1s(Eh2T!x;g%^BJR>Dwz(jN=cr3_=Zzm2n8%tlYbGf1CT|2;rxE9 zDy^PPgqV?K=v{0LYmiUzOyUW4afM(vOSr)U7!$T7WzY*aJXH~QGpkC;F_uaAvR%(B zUUW>eM^j!AD}D4Br8h=u;o<7~{>RGgz{e^(E=J$nhl7G$T%d5|>P?%#f;uK~QBlP@ z@d{K+`;k9?+fN$gYP^Qd!T~mIk)&$z17C|3G&Yi1V@1(~_PO6#!2n~Le6tUdIaSF^ zC+Z+u*cu*gtZe7FHCgjJB}_Ydme zwlf)2OCV?w?VFmA^Q%`;f}fMP zLI|m6o`GS(G?hZ9J4F*c=o)3lVhYZQuE?i3vZSTY@gRA8`mTo5q-nLGmwIdp;Dv{%U0qQHhS8QE~p5OB4BNnNXL}~>F4$U<&)qu)r zbOtfrE`0HPVX75fn|W54sjZ^se^|2~PkrNyKbsk2?effzSPIH{EFM~?vZD7Hy=cV% z`uT-q>eH!!KT~aI#cgM}ZF{(FXoohmSHQ7X%%h?|i&uXZ|1#4Avs3bp(<8I1BS4MY z0*po1eAf6-^gPIgrm7a-mNNM-Kuh(-8*T(cBUy93O0v%KZa+7{`a`k%8+78lpyOuB3%`RDI zkL$Ua{f>lbg*y<(k}!>pFPq=``oi*`uI-0~F6tP03^kIpmWfxYykev<)>Y5cz48uPC8Ir+Pj`dyU4{v{W7oH>h&INSxe&r(EYi*# z0n55LTJZxn8*mv&e~~2si@_|EX&h|3DR|Nu_)bx(2Iq$)Y(C{Tvh5Et;6Nn6?NIM> znf`Kl9Uf3`}8KEi}8dQKva7oa0aBC9l?{ou9AA5i9#*wrs#b4`i} z5k9_b?e;CKp__8QvRqsBF>6sR-;eyOFm`I8F`?{qi4zjUk{k4bv`^fSs}7Qo?>`}@ zJtD39Aac#HRnGf0{C@{r?Owg|6}>vmyh>Iq_%#BeiJI8|Yv(IhSAHNkB_x3LIiU5f z+v1aT!aMQVnj)?J!D@H4#>PgR<&J@ihzx$xaf63Qcm%v=jPS`0p%fs{XXBWK`jBon6%vrW`I9+~hd7N3e-&3z6L6XsaJnB8a52ixPdls=;_GOZeEuU8%+l%&8H(|}R~dX5-*5XV_@rN- z{8{l6UCZBxUzi2&O52*3t|hUW-@r|$c8-u)r?sIM9(_Rpo?b9lvd!sSe{jT3#2p{8 zPUV5pIJE#R!_6-mvXkPYf+CZ9?_4tHWZ9|l{XUD&Orr%~n-$X-N+$k5s*~itg253j zhm>-S9#uYqAj1h8)#y{$XkyBGf&;F_ZJ^Xi;InVn=N`&45Za0c$|_em+}ZyyhaMt+ zY73TLA8I6H7#SJawQd9i91vzCt?=1}$w~5}Dfh!5%(x#KQ-`amgtrc(*VP^$^*v5S z+poDktF5RY61l<=pqKEavIfI@bQkUuTDPTCSeTR27Dm0t8oIpWXAOi%T&Ow>j2jOy zo8nho$f869B_-*~!Q`m65}+tNF!+|V^}z?DD_!I&*DH6SGOPV-T;sc)F!<*>5}htL zoG!OAFSnRGmite@p3`)kmM)%^_6p77+OmD#^sSGhd!->lyBMJpg*kwQ=*1@LJT9#1 zX6XE3p>~%zfc0+7{7*@Q*VKc&@h7!g0#4TOlmI5WM3(l@rvU*{`+M~n`d|`Y;^eue z7EM1}rfDwS2~A@@!LW--6qN9;?yNM`BoIf56@q-~GKyBy>9r}IauB-}$%eB;+130v z+Jv=#Mi~NF0`D9h?mjEPc4|ipa<=2fw4Jam2XiD2Jo~N#i{WWFd_YJDNdT=S`pdmg z;4Mp?eT$(pd8jISbrN%RGSGH0pn=E!Wao3>a<#-9)u&IB6(YI0E~xM`xuTb8qiY$J zmUl_5&4y@ryk%CNTTe$&%cj}FlGX$Xj1$N6&G8?)j_Z{|V{nx;GKoe7(J`r{<6vY5 zQ_6rYO9{2&<67A$+t6h1dL+i726{j$lCRu zoUN&ZOjhS^J_qwDRE2Gm32gGqRo7mP18s`L>xtKO{%&s7Ti$|e6lc&?>i0t=uMi{% z_8LH_9SlXJrF9)*pA`!*eomw@8$wL=BMRtK9#*P-w=?{L%$;GQcS)6$Pz-NO7iKyS z3pKK~gEi`Z?vXWXEE0kZkzqYsM-d9tR8T4o}t2f;IG$TTNK&){}40I45TS<~27mR9Kns|Eu^sT$*cG5vl z<6jVi=T88m>3U`?b*hVW(3zh>)fDFX-vrYIZ2CS)9OjnDRZlRIeNg^>$YyfN5LIY2 zpLLEjeI(^z4+qmuPJ?KY>gN{$Je_WW90s?Cc;(7dv{~ilv?|xSoSiGQ z3*C2_kDosc2J^-tAt8IA?)D&6aZ9}x>3~fYet$jlx3g3Yn+T&!ih|xSF*0M@Z#>p) z;gx;K$8%(cu>jj6P|9y}BA|1wanzZOwho zyi_TBf|-0~O2MPw8i=rft}csG&xXw(&p8y;k*4D>un*!F&%))UWWCRnY$tgixD1#6 zPSQ{G8=3wozo{u>CCNCe@z@Gjo{-%_fb#oKRVZ?nO%{v%C9uX=C0jIsEz-HDuX6`7 ziC)+v3d7PbPBx<3cYfsLD3nxd6@5v5I;F)>RAbRxM{NI;~j3gqF7!K zH=CraEyiYd{j@$GlW2dI-%q0!Dc)+>SG6zmjV=}on5=mcpU}w=Bo^$CKF*1^l@p z*vU_er+vCQhsOKe?jL7{F*d!s8@5OKsZjhmIerhKAiRfELoB5{OOQmlW31xlq~_u{ zx=-PpI(IP-%q@_x4S8i;@-tsCbI^$lOJmN`9johj-7ZfHvD3|E6z7z6oX+2x)>4yU zTaboGF7Lf7wPUdpW-i(#o6UNeoG)D2+Xd`-@*_2B2$LJ7mobG;TN$fi|i}z zz?8p;4Z?iFR?rhn6DIRn>|tCd>yl~`#nU+6V8)s0$beOu10#Cj3)b~90i_^g!6k_! zIoX;DW(D2Ds#pQ&+1@NwqzOp&c1cMOR+PEyi<{-*4`zwhzJ!=zm z(1waNDeAQJsf>G(eS3SIP*XMjfEdx{_tyEh=Y-c|6fp$xJWpz&8`f(kt1#B!Wm>=f zY(G4Xn_i|QO$^{n&VM^0?dUQeF16omGtsx!4ytF_7?dJ!8>giensNeC6NuSx}=EGPfQskm<=8rd}LAMfbq?DWeWO%E%0R62Vat9Z zFo+mY2{~#G-yGHHq>_^}uF4BI%!w3W4Wjh`*ciE2mD=Z5bYWwmA`Q zc^9807D$9yxqcF`#{BDs}hh9?_{Id;UCOKbXw+2QP$7pvFgs+z%P(G!vyxO(E16Jo_>#wCBbyxDSvHlHh}4kX3*+eN zU2{jEx3 z!Bi!~tGVT+tmTf!z_eZFk1Kn=C%po9)z)}%2w3sgnRC_*gYt(=xf+}ccg z%Yq#m>qz#BFEO>xXVKGnqI4e7-;-V*Xi*@@h;GX<06TwQWQzBFxAe9yrgOx zSN$gBK2$TsX-@(h@^tz=zNper+grN*yWu^IRpAZW!IFMr0VHgba$nm;X__jS2O7#o zdtSRgnWsE47%sA?u0grnDv`UD^6_4!X6K(5X@G0@Ezgm)w8ywBkdkTEg&!}9t z^i(l!i{g`S5chM;t=CZvut8%2!Q4_%($K`2G?(@B4kwF*6Lz6ZucU>PMcEG)Nz*F2 z>0au-9XbV^MRs!4vpXF*n5Iiwc80goL(a!+oHeh9wVJC?arJdnL$yf8ItL-;J_ksc z_v@4}A=EE>1~zn333&fr^(fAXznh`;iS zmaak$U6q#^I)cehPDnWawBy?kB6vLcDoRl29 zE__+NZ(0-*MHXN7DbD^UqmS`Y(T}#57};-<>G)c65;_nsO*_zv=Y}5EKRgu+Gp#># zybPjox3dfP`&k<8GF^!{9u9Xf$Rya#Sw3up7y=TfbfdHF)K7B0yFNa1Fg2ALzkYgg zG4scMCkOcr@MuG~4$ks%eJvGRSxE^CC&eZh$hP9jS6L~HOIn$^2;;7Ow&L{3^B%L4 z087*Lz?|s}T6gg-d7cn7yb;Ho2!m36J%tO56s8yOWL1or=q+V@4kjRxt*yxGrf9hx7~c<(EuF3N;K_XrlN|rUFpFLw-?qNsq`!W&B=??^ zO=}MLtpWJep(x1NC)1z(T{>Fa33c5vyx=!hte6_dHC}~sI7MaMKXe2S2i-#s4Mp{& zV8i%?Zfe}adjO%2`ARlvq`3OKtHtkn1eCp*_9Yxt$nf0`ksFKUu*U4ur(hIo9CbhS z>w+Mg?%Y0Zb#JF2rs@x^#}f>6D#7d9EMyUu&x$X%wh^CN*TTQ|q}Unc1Ur;vDI8za zYEPpFRi+n?jyxo$yQp8g7pV!A(aVC#Z6^lH&V>)7g_O}>+4KhUhnJ`@cFMk0KWaDP}-}o9vFFdn$JhwNN3IihmjSx$n(C7H9;0dXm-x8B$_G=IEUl)vc&zM^H z(R1lGLHt?d^>k%gc;jC9{@NJbQaB*$fdpJHjeUyN9==_+Xv5UU{Wj*ChQIaMQ$Ht! zLHX3cdX-H>zZL(QYPnFa@N>)JH*Yf1!BeHYz1NSNuZpKF&__?YQ^Y>wA#rQ1T?S84 zO?oGnatmwikZDMVkqdF9;N0G|o9+g`cLYCQN=(e>>W6Q_VXk&zSI&Jm0*PgoSLU)@ zV3ozOckSnPom-5dww;|S#O$dOTqPFSmy?H5`)&iJ*m|8QmCOWS*ahjvhRjBI9j~_+ z9b*Uc^ilrmRB6=s*k4X3K>=q3DEa$NW1@2#{Z4cV;vE3W;r3Nkmv{AS-HQ&n>gXH>9j-1i7V}|qF!ltuh>aBhq>2rMNii}(Ip)cg2*x{lOhyeZ#Br@O5tU8xdlUL z432qD{ZJ|r6DBG6P&Uq)pbSk;!n}2Jg)y9x`wETTWmgD~CN1z>Arasv|u-|tI z<~2AP$kN<)sw8a8Q-o9rOl*!%o~~1ePh&O34~BeRI)-eHU8j$#!t?@|Sd&1Wu?vt0 zv$6j1%XH7}V>!;XJuVq#mwgEhS(>Q9b6ivR{XWm< z{XFj_SWD{&i4?aXm0k9Yum6H!CeOL$%se4~U@uL~tz-F&A-CQi;J z)hvd0f~#|#p@6(cez54Ky6Zlu01}fvJRH&3X_WJI!lccZaA!1U_v6$4c~RYSk%s&@ zVt4lBeNomolHw(NZ=2+b%_$O54K&`QWymE zz7S{cmrx;MJXp80#IG&;#jghM#7rdRe%h~(VZA6jKrIfAk)6$u;9$A#HkhEZsku~ak132 zZtSu@+ei*M>*B@a2Od+#_FEbjEh{gz33n(hUw}5$GTAaLUy)R>5*WN+?^H@l#NMzY zBx5lY{x22ONn6dj5&PGs7uw_7cn!(nT3H7s!9SuX-9}G$iOjvV9QgUc%wOYHCoT+d z!=6YX>=ShfhZJg$Gn$X4p?b&Cl0wy%ns&C`=3r_yoO{k<5M5XO=+9z#W0^tMH&Upx zS(zS8B+XH(0hOR_GS1*8b>~I)F2lPG4}>@?BxdRHS>&vnw_T^eyK&^j?PJQ$#pheY zm5&}hlIdHYg7eJUKm;?;x0MpyGb(nW!czCaCBDqeuCa{6@BJ1l8n?%uNp$%>qaka) zgwn9b$J46eQ2UkMYm%(V6&0?^E)-D6_z|`DaoT+;)NCNmBW1htcvhTYgQi-e^fV`) zxBb{iwus!Y7%!K@lzsTFW&B*DLBX0fWZ&j--0cBpPX)hK8&)xiWmpamVP2moih08C zU*}j()p<3`1{TEVOL|X)3&{Kd#!?UFd0hsy1V2u?cRx$bI!!Vd1AEH=xl^b3X4jEm z4g+0x(&v|}f30YLTvt>sfCN0{jdvn>wlZb!)}El_aa&NE4sd+UD9N(+M$gH9kFM>R zM-jwWwMU1B@b@fCFS)({nIKWPq`AVmHXbQ4;1UB2oiK8&WthcdjPo-oyzC)<%w3E4 z)vp?j*?*ltd1_7t*oD3IxBhb}-b&rHanX2jpwEJE*qMWCy1_*zG4Cp|-3qOCkA2K8 zUO;Gb_0ih-fegSCJn#w4D#VG@MPnB5bs+uw zAK54-AEjQkL2KcvIj=~*XV;Lus4<6q4?$Z*_DUsxk{Q^DX;Z1_KF;~a`hJW&!2?v`HdUwFe!WWrkK}_d`XvwGM8d*Vw=o}CNP`{GKK5t2`g>rnZ{azM z6~{=7@t?Ls>b6o4(lY@>cZZQta9q&pjo0JZBb?@%H z;GT!q?`_Hwh$i1^JK-`+83^iY?5dg%3jWigM@CUG+j;-kWlcs8l$L=rEn& zqhg!gLGzt~y*;So6R*{GFi*GZgK;!>$XlB$+HpM`)gmpOO)1?c2XNC`tjZ^u4)tEl zI62HAgpqq1*TK(z@vZM1?0&gV$g6R5-CSW9jLU1T5@jDNEmU@9QBTq0Nus=&iq5w& z(|cnh@P4i&lkeo1$CZ)oOB0iSKb;KnEIL7Gt&xENEp5$g9h}#>KH?ck<`<~1uO~3K zpVZ4QD#$7b$gDZK0}s>rzP`dEq`CaA2fX&w!%ut@u6Yg zrHYr5mN(t(PK{B|Nl4psP1mYdrXnukRP&Ikh!5)*RgT zB&3BSZ0AI1u+C|`yxq`sAwP)_shkFxP{WizYpoP`d~9t+oINiRyUQlc#G9G(UCQXw zuQ(~l+i9I)Qcc;dR2VU+<|yq{inqKjPvCmPZ#g8N65r}F&=h^9+3D;Dw_UNDyM&6@ z9!)UKoKoQ2Rjalx6t1(lcHw?GgIVAp&HPj?FzCR1y}<9%%0Apd&(VDVM?1*LImR)PaTjvNFFet{*TM1Uvy}xU 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 literal 0 HcmV?d00001 diff --git a/docs/webService.md b/docs/webService.md index 41eef8f..b4e2135 100644 --- a/docs/webService.md +++ b/docs/webService.md @@ -23,7 +23,7 @@ The models are used to represents the concepts which are gonna be manipulated in ![dao-dto-model](img/global_dao_dto_model.png) -## RDF Resource Definition +![dao-dto-model](img/web_service_architecture.png) To represents and manipulate the triplestore resources (instances or concepts), we have created models, DAO and DTO. ### RDF Resource Definition model From c3683dca973b90244cfaf2e748ae2d95ad3ede9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9as?= Date: Thu, 4 Apr 2019 15:16:13 +0200 Subject: [PATCH 5/5] Add specifications to the use of DTOs and DAOs --- docs/webService.md | 49 +++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/docs/webService.md b/docs/webService.md index b4e2135..1448e85 100644 --- a/docs/webService.md +++ b/docs/webService.md @@ -8,45 +8,58 @@ layout: default We are using the DTO (Data Transfert Object) and the DAO (Data Access Object) design patterns. +### Model +A model is used to represent a concept manipulated in the web service. + +It only contains attributes and eventually business oriented methods. It doesn't contain any storage or technological references. + ### DTO + +A DTO is a object used to carry a model between the web service and the clients. + ![dto-schema](img/dto.png) -The DTO objects corresponds to the formats used to exchange with the clients. +A DTO does not have any behavior except for storage, retrieval, serialization and deserialization of its own data (mutators, accessors, parsers and serializers). In other words, DTOs are simple objects that should not contain any business logic. ### DAO + +A DAO is an object that provides an abstract interface to some type of database or other persistence mechanism. + +By mapping application calls to the persistence layer, the DAO provides some specific data operations without exposing details of the database. This isolation supports the single responsibility principle. It separates what data access the application needs, in terms of domain-specific objects and data types (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS, database schema, etc. (the implementation of the DAO). + ![dao-schema](img/dao.png) -The DAO (Data Access Object) manipulates only models. It does the CRUD access to the different data sources (e.g. triplestore, relational database, nosql, other web services, ...). +It implements the CRUD functions to the different data sources (e.g. triplestore, relational database, nosql, other web services, etc.) +A DAO only manipulates models and don't know anything about DTO objects. -### Models -The models are used to represents the concepts which are gonna be manipulated inside the web service. The DAO only manipulates models and does not know the DTO structures. Before using a DAO, we must convert the DTO given by the user in a model. The DAO will then return a model which will be converted in the DTO corresponding to the representation of the object that will be returned. +Therefore before calling a DAO, the DTO objects recieved must be converted into models. These models are sent to the DAO. The DAO query the storage and eventually returns models. -![dao-dto-model](img/global_dao_dto_model.png) +These models are converted into DTO objects. They take part in the data returned by the web service to the client. ![dao-dto-model](img/web_service_architecture.png) -To represents and manipulate the triplestore resources (instances or concepts), we have created models, DAO and DTO. -### RDF Resource Definition model +## RDF resource definition +To represent and manipulate the triplestore resources (instances or concepts), we have created models, DAO and DTO. + +### RDF resource definition model To manipulate a resource (instance or concept), we extends the RdfResourceDefinition model, such as the following example. ![rdf-resource-definition-model](img/rdfResourceDefinition.png) -### RDF Resource Definiton DTO -A few services returns more or less the same RDF resource definition JSON format. We have created a few DTO which are extended. In the following example, the RadiometricTargetDTO extends the RdfResourceDefinitionDTO and the RadiometricTargetPostDTO extends the RdfResourceDefinitionPostDTO. We have created a specific package which will contain all the DTO of the radiometric targets. +### RDF resource definiton DTO +A few services returns more or less the same RDF resource definition JSON format. We have created a few DTOs which extends RdfResourceDefinitionDTO. In the following example, the RadiometricTargetDTO extends RdfResourceDefinitionDTO and RadiometricTargetPostDTO extends RdfResourceDefinitionPostDTO. We have created a specific package to group the DTOs concerning the radiometric targets. ![rdf-resource-definition-dto](img/rdfResourceDefinitionDTO.png) ### Property DAO To manipulate the properties extracted from a semantic triplestore, we use the PropertyDAO class. -## How to create new services ? +## How to create new services? You can base your new service on the Provenance and Radiometric Target services. -1. Create the service class in the resources package (e.g. opensilex.service.resources.ProvenanceResourceService). -2. Create the DTO (e.g. opensilex.service.resources.dto.provenance.ProvenanceDTO). -3. Create the model (e.g. opensilex.service.view.model.provenance.Provenance). -4. Create the DAO if needed (e.g. opensilex.service.dao.mongo.ProvenanceDAOMongo). -5. Create the ResponseForm (e.g. opensilex.service.view.brapi.form.ResponseFormProvenance). - +1. Create the model of the concept manipulated by the service if not existing (e.g. `opensilex.service.view.model.provenance.Provenance`). +2. Create the DTO that your service will manipulate. It must at least extends `AbstractVerifiedClass` (e.g. `opensilex.service.resources.dto.provenance.ProvenanceDTO`). +3. Create the service class extending `ResourceService` in the `resources` package (e.g. `opensilex.service.resources.ProvenanceResourceService`). +4. Create or complete the DAOs corresponding to the models your service manipulates (e.g. `opensilex.service.dao.ProvenanceDAO`). The DAO must at least extends the `DAO` class. The only functions of your DAO class accessible by your resource service class must by one of those define in the `DAO.java` class (create, delete, update, find, findById). ## Java Bean Validation (JSR 380) @@ -54,7 +67,7 @@ When you create a new service, you must use the [Java Bean Validation](https://b ### Use an existing constraint validation -You can add a verification on the DTO for the post and the ResourceService classes for the get parameters. To do that, you must add an annotation such as `@Required`. +You can add a verification on the DTO for the POST and the ResourceService classes for the GET parameters. To do that, you must add an annotation such as `@Required`. In the folowing example, the parameter `url` of the method `get` of the `ExampleResourceService` is required (`@Required`) and must be a valid url (`@Url`). @@ -147,7 +160,7 @@ Create the custom validation annotation interface in the package `service.resour ```java @Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER}) //The annotation can be applied to a method, a parameter, etc. -@Retention(RUNTIME) //The annotation should be available for reflection at runtime. Example : @Deprecated (see https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html) +@Retention(RUNTIME) //The annotation should be available for reflection at runtime. Example: @Deprecated (see https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html) @Constraint(validatedBy = {URLValidator.class,URLListValidator.class}) //The constraint is validated by the URLValidator and the URLListValidator (to validate lists of url) public @interface URL { String message() default "is not an URL"; //The message element value is used to create the error message. (see https://beanvalidation.org/2.0/spec/#validationapi-message)