From d6591cd68ed88385dde523c34e07204a8046cbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Fri, 8 Dec 2017 11:24:59 +0100 Subject: [PATCH] some renamings, clean up, add Bundeskunsthalle harvest, update to gradle 4.3.1 --- .gitignore | 1 + build.gradle | 44 ++++- gradle.properties | 14 ++ gradle/ext.gradle | 4 - gradle/sonarqube.gradle | 6 +- gradle/wrapper/gradle-wrapper.jar | Bin 52928 -> 54731 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 172 ++++++++++++++++++ gradlew.bat | 84 +++++++++ oai-client/build.gradle | 24 +-- ...AIRequest.java => AbstractOAIRequest.java} | 18 +- ...Response.java => AbstractOAIResponse.java} | 4 +- .../{DefaultOAIClient.java => OAIClient.java} | 74 +++++--- .../org/xbib/oai/client/OAIClientMethods.java | 105 ----------- .../client/getrecord/GetRecordRequest.java | 4 +- .../client/getrecord/GetRecordResponse.java | 7 +- .../oai/client/identify/IdentifyRequest.java | 5 +- .../oai/client/identify/IdentifyResponse.java | 4 +- .../ListIdentifiersRequest.java | 5 +- .../ListIdentifiersResponse.java | 4 +- .../ListMetadataFormatsRequest.java | 6 +- .../ListMetadataFormatsResponse.java | 4 +- .../listrecords/ListRecordsRequest.java | 4 +- .../listrecords/ListRecordsResponse.java | 4 +- .../oai/client/listsets/ListSetsRequest.java | 4 +- .../oai/client/listsets/ListSetsResponse.java | 4 +- .../org/xbib/oai/client/ArxivClientTest.java | 67 +++---- .../xbib/oai/client/BundeskunsthalleTest.java | 112 ++++++++++++ .../org/xbib/oai/client/DNBClientTest.java | 70 +++---- .../org/xbib/oai/client/DOAJClientTest.java | 76 +++----- oai-common/build.gradle | 2 +- ...AIRequest.java => AbstractOAIRequest.java} | 4 +- ...Response.java => AbstractOAIResponse.java} | 4 +- .../getrecord/GetRecordServerRequest.java | 4 +- .../getrecord/GetRecordServerResponse.java | 4 +- .../identify/IdentifyServerRequest.java | 4 +- .../identify/IdentifyServerResponse.java | 4 +- .../ListIdentifiersServerRequest.java | 4 +- .../ListIdentifiersServerResponse.java | 4 +- .../ListMetadataFormatsServerRequest.java | 4 +- .../ListMetadataFormatsServerResponse.java | 4 +- .../listrecords/ListRecordsServerRequest.java | 4 +- .../ListRecordsServerResponse.java | 4 +- .../listsets/ListSetsServerRequest.java | 4 +- .../listsets/ListSetsServerResponse.java | 4 +- .../xbib/oai/server/verb/AbstractVerb.java | 15 +- .../org/xbib/oai/server/verb/Identify.java | 4 +- .../oai/server/verb/ListMetadataFormats.java | 6 +- .../org/xbib/oai/server/SimpleServer.java | 1 - settings.gradle | 3 +- 50 files changed, 645 insertions(+), 376 deletions(-) create mode 100644 gradle.properties create mode 100755 gradlew create mode 100644 gradlew.bat rename oai-client/src/main/java/org/xbib/oai/client/{ClientOAIRequest.java => AbstractOAIRequest.java} (88%) rename oai-client/src/main/java/org/xbib/oai/client/{ClientOAIResponse.java => AbstractOAIResponse.java} (55%) rename oai-client/src/main/java/org/xbib/oai/client/{DefaultOAIClient.java => OAIClient.java} (66%) delete mode 100644 oai-client/src/main/java/org/xbib/oai/client/OAIClientMethods.java create mode 100644 oai-client/src/test/java/org/xbib/oai/client/BundeskunsthalleTest.java rename oai-server/src/main/java/org/xbib/oai/server/{ServerOAIRequest.java => AbstractOAIRequest.java} (95%) rename oai-server/src/main/java/org/xbib/oai/server/{ServerOAIResponse.java => AbstractOAIResponse.java} (70%) diff --git a/.gitignore b/.gitignore index 86023d4..572afcd 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ build /sessions *~ *.MARC +out \ No newline at end of file diff --git a/build.gradle b/build.gradle index ba6e490..bbc02cd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,25 @@ plugins { - id "org.sonarqube" version "2.2" - id "org.ajoberstar.github-pages" version "1.6.0-rc.1" - id "org.xbib.gradle.plugin.jbake" version "1.2.1" + id "org.sonarqube" version "2.6.1" + id "io.codearte.nexus-staging" version "0.11.0" + id "org.xbib.gradle.plugin.asciidoctor" version "1.5.4.1.0" } -allprojects { +printf "Host: %s\nOS: %s %s %s\nJVM: %s %s %s %s\nGroovy: %s\nGradle: %s\n" + + "Build: group: ${project.group} name: ${project.name} version: ${project.version}\n", + InetAddress.getLocalHost(), + System.getProperty("os.name"), + System.getProperty("os.arch"), + System.getProperty("os.version"), + System.getProperty("java.version"), + System.getProperty("java.vm.version"), + System.getProperty("java.vm.vendor"), + System.getProperty("java.vm.name"), + GroovySystem.getVersion(), + gradle.gradleVersion - group = 'org.xbib' - version = '1.0.2' +apply plugin: "io.codearte.nexus-staging" + +allprojects { apply plugin: 'java' apply plugin: 'maven' @@ -16,20 +28,25 @@ allprojects { apply plugin: 'pmd' apply plugin: 'checkstyle' apply plugin: "jacoco" + apply plugin: 'org.xbib.gradle.plugin.asciidoctor' repositories { mavenCentral() } configurations { + alpnagent + asciidoclet wagon } dependencies { - testCompile 'junit:junit:4.12' - testCompile 'org.apache.logging.log4j:log4j-core:2.7' - testCompile 'org.apache.logging.log4j:log4j-jul:2.7' - wagon 'org.apache.maven.wagon:wagon-ssh-external:2.10' + testCompile "junit:junit:${project.property('junit.version')}" + testCompile "org.apache.logging.log4j:log4j-core:${project.property('log4j.version')}" + testCompile "org.apache.logging.log4j:log4j-jul:${project.property('log4j.version')}" + testCompile "org.xbib:bibliographic-character-sets:${project.property('xbib-bibliographic-character-sets.version')}" + asciidoclet "org.asciidoctor:asciidoclet:${project.property('asciidoclet.version')}" + wagon "org.apache.maven.wagon:wagon-ssh:${project.property('wagon.version')}" } sourceCompatibility = JavaVersion.VERSION_1_8 @@ -40,6 +57,10 @@ allprojects { options.compilerArgs << "-Xlint:all" << "-profile" << "compact2" } + clean { + delete 'out' + } + test { testLogging { showStandardStreams = false @@ -52,12 +73,15 @@ allprojects { classifier 'sources' from sourceSets.main.allSource } + task javadocJar(type: Jar, dependsOn: javadoc) { classifier 'javadoc' } + artifacts { archives sourcesJar, javadocJar } + if (project.hasProperty('signing.keyId')) { signing { sign configurations.archives diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..c5ac801 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,14 @@ +group = org.xbib +name = oai +version = 1.1.0 + +xbib-content.version = 1.1.0 +xbib-bibliographic-character-sets.version = 1.0.0 +xbib-marc.version = 1.0.17 +helianthus.version = 1.0.10 +tcnative.version = 2.0.1.Final +alpnagent.version = 2.0.6 +junit.version 4.12 +log4j.version = 2.8.2 +wagon.version = 2.12 +asciidoclet.version = 1.5.4 \ No newline at end of file diff --git a/gradle/ext.gradle b/gradle/ext.gradle index e541663..dbf635a 100644 --- a/gradle/ext.gradle +++ b/gradle/ext.gradle @@ -5,8 +5,4 @@ ext { scmUrl = 'https://github.com/xbib/oai' scmConnection = 'scm:git:git://github.com/xbib/oai.git' scmDeveloperConnection = 'scm:git:git://github.com/xbib/oai.git' - versions = [ - 'tcnative': '1.1.33.Fork23', - 'alpnboot': '8.1.9.v20160720' - ] } diff --git a/gradle/sonarqube.gradle b/gradle/sonarqube.gradle index 6d4c3fa..0a37566 100644 --- a/gradle/sonarqube.gradle +++ b/gradle/sonarqube.gradle @@ -22,10 +22,8 @@ tasks.withType(Checkstyle) { jacocoTestReport { reports { - xml.enabled true - csv.enabled false - xml.destination "${buildDir}/reports/jacoco-xml" - html.destination "${buildDir}/reports/jacoco-html" + xml.enabled = true + csv.enabled = false } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 6ffa237849ef3607e39c3b334a92a65367962071..6b6ea3ab4ff4f69d55c5fd9c0a6ac70f47d41008 100644 GIT binary patch delta 25672 zcmZ5{V{oNG*KH=8*tTukwr$%u(V1kD6DJefwylXL=ESyb-nn1hs_%X8Q`Jw^?%KVo ze{|LEUVE+I*%0HE5J)QW5Re#PVBf!kfq{vF#Ul};|8FEIY%U@CZ(b{2L{%{3821eK z*6qga8`yuZ`Ii6&{(pb}KFEK=+0B|6;{VHupCE<%U)=a7+W&|e?bunM{v%GL`?iYx zzsY0HeD28q@J0S%b0o%V5&^>W0o}q8Ne@ zNkf*lu9|g=a*p<)6%5aqh{GW!3JT%2YK~^F9HFpPE0@1af89nY_|IXl+3X@;OXFUF zX^O%A4M_7l%5lFE^tO6Ds&y6yOS)N>LgU3pa>H6gYqK>c#D{gDsslQ#>vOfZtVv-2 z;McG&Sq5`o@@sS1CGJ86K{|?DPy=ck$U|qFJ3%VW&!QrztxWg=%X?$oZ>}sQYk{eC zgp_g6e{-CoRNfG4ip^Y%Li1Ice|UEW^AvYzFxD3Pu%j3m-zZ7bT!o&81?^8xHbT)M zj5FqY({wXyx`W?Y{sGp-GcRo2A+N)SK3XNxVO_HQFclPT^=>zVjw49MaXUi6JvUrY zN4%Ni-YZqgFNohI36-pHjb#80wJc_vjYPk<&?klZAw^yv6MTV}wnNkE((t#%!ITV$ z!^h!7etD-MqzhM+{P^3B&R!H2@eNsj^D?h;h*W%TJt|>v0RjlB_74ayNG5Kf3vDC? zQL~4CrDf#A#(!tDcdV(9b45cP$9}X&Sixm{v_JIKK8%jwe6=S?V~z}Om-OY3Z@T+4 z2jAcS$Vz7XCxS%L-XG^ZJgSM09NfTw6ki;A#nmmj0D3%7`aT<4n=Ry-MB)4ay)mrqUu_ z=^gsNkLs@*)G1^nFfb~D#8^#gV74y23C5DApz`VlZj2PMmQ0<=wb^g1S3LZmj0jR_ z;E)L@dK3*N4slK7wx*oq(^KGX`rNVNyBvz^O|C*pX4Fc0PsZmUOjxD!5=N)_#Sd=B z#K1YOj}F^cMPb{yyUoBRJx7evmWRWD%YdgIzv=F)o`<8}my>DmWm+a2pv-nhkZG63 zz^1juo$g8(L#ForDf97jR*>-^v+c7b1hf;54`#2~w)PERM*wa3r)5c)UVqJMxuyl;d+`|Ydir{-svE~jnc8%;uXx5M0hCF4YPg*77`<0X(nbX`5m7&Ap&}2vWsaX`0)9jE|dmopg!_r`NMw=oS_+j4OvJr4h zuJocw#Am^snepE0U3cv!Q9b3#7yO~nd;~cTanKC;krh#r+`a(Ze*tD3< ztGTIA#Bu96UmOBxjyw#ljI04sods9Co{pQ@=|JGtoqmZsEmw4Y8I{8+?CiH8Zs%J2 zWB4YV(^@?=-+d9PlHZb-eS>vNo{!ytt4+Yv@1*GLJI9pYWwdqay!dF7Gr!y2lw2mU z2Qwe-l3a93ynF9Vw=DI^751^cp=5P(Mpf1dD=EscH~Ipw%arD1nLNE+c8%Xwv1CDa zotB={6d=nxr40SPLZR4g%b8qW&{<)%HR-x_%<7ckmVL6XFx)tu|Eb1!NyZFRFKNkURN=5h+VIzUu4Ree{K!;RTG^_klv1o>>Ry$Ynw{H9e&ftXOK*g@ zAsZK%(nD`ju{9|}3i+a{7T;r{m1*$JO?B;Ie2@)=z)!A14ys}!nt4V|VCp7XIQPcZ zVl89OO*7$qa_FyUsfVh({`_NGD#o&b)e7Ok;@%A~F~g>qLa%LFj=FTLyScEyU8{m& z!$JXb#G{U5Cy)JtjaNa>*6*q2o3-4|+u|ZzTRBE`40}ti`7Ov1xLAC^l{5o*^oX46 zaJMhwc9b;8`|Bp|3}E6B0>moJjksOb>}~!yC{9SIXb-9Qo(aB_gVz7+mYn}gjz{AX zUkx6(uRGwAJyyi9MZ}!3lQOoc6KG}0C2h$Pki&1}AxK2o<-iZ65Y$|a>CLjg9&$lp zF;zW@c#G>iIj82zv|r*5+c>P4s`TiqKG=xr&c2z%SQx>=WYQ*oX}(KFlsuWKII(An zPBcg5zhdFiH~6$S*|br0HSIk)E8OLZ`$Dvs?lVdZb@#1ISBVs^hhgE_pmKk z!)T4lE@=~Ax7~&98XAPTX`=Ot=u8WQQ=KgpTU1IKM*3O9A)dq}i`r?~D2?u&xl1%_ zzDw>iJP7X-5BhcLO*d|DR!e({`KC~Bylx!{QJ{?;P;!h7!^vtADZX1r8!I!ElYk90 za8x_|#>{@T2CGQGImF6JF{6R7u_svuD*=ZUZqzh4i#E(uj=i$K5~j#X7He;|fI&T& zMrBsQLp!X&djM zvPmM-1EtZsRJ-;qq~<&%rPaCSe_F^>;|k0wsG3wor6ukfFu%wM5m(bo`x{fGtM%cG zl~Y%XI|L$3r<Fc;O|A>LB^7@sZ%^6hK zvz<_MAnElSFi)&0^m+W~uw9&RhY&8+Bd(Qj4tjC3ZDci)8RhM?m~Mn>ll`fEt;pxg zdNN(J`)0v++7`%>ou2DmE=~pfYwEIX4rxiuOog^|=)0+wr>vnF>H|Mxq^i&pONapedV7XHz17kD z(eXn+l5I@RncVRW=E9afaksm^exFEBs`QaX{*HW4+0GPDG#Y~spE{)$gPFmfE8}ac zxspxQ6OdXg3VWcY+g##l>4fAIl#Qv+R~T$St0=yOLzOj;UO~3j z;bB^NYJroKJ-BVj!J-AywxuP=DKvDUB|<5D-Gaw+;V~$F72`t*XsSc&Pv6THpebZ! zJ=`8x4JY={M5m^Lwd;;m%a_2UGR4iwxoVVz7X&I|me3j>pt@;R%omOHT=)g+{1Oi% zb7r=@%x&&UYieV+WTyA?#ccMUR>^$4+GQ2Hfa8{rj$lbF`ECuA%4sgI8sqcTIPGdd z8}?a?Jj+&cc2Fsvl(!v9Y61X1X)!xlSfseF4#3zfaOdsrCBQkGfaL ztLphm13o&rv5A0`&2vti8f|%!iCBdWgg2F|lZ&>~>_OkND=wseiYp2VmU7gsP*Jak;_Fr~F zNo5AUQ6VLU&QrJJu_}FPn6bY~`>`lk5WeA)I{fC%vK9tH<-xfV@Kc&&o4!bx2s0SN zo}L}``qN+A|9T{2syE!WArOUpuC}$uCd`gPVJ>qdQVr2`D4e1F^jo$cN8RO zxzLhZ8~y;c6cV+XF*=DuRxgJT%B32%6GnA7Fr7B&5;n>`2oy)1%T|MD9mvzx{v|D@ ztmCRO7N101Fb+e-jw}E6$=|k-eSW33Ch5*FRLHUI+NBv`^V<^G6_e#`E&My3^)Z*`dnFz<*1ocj zXVt!M@Ws+h+E7N$jAzK+(kw>lc5{>sQA9|C%?WH%vov^=jEX7f>2BTT<>*;P())z6L>y(6gZy@?w? zRsU2dv;~Ea+}G1x5$j?ac$OU*_IMTz=`0cl*?4@~71T1t(2+Z`m;)L+%P@%J=z0(C zU$ytirt%{+*4)ZE0jAl2Umli)VLZ*fzl8&%J_eTp?ytV_6=VC&jsV|S!@otNk+KpD zL&mZ^L*v>=M^u?h%&-u$1yj2cC?}qx^91FV*azk;xzu%ng&+0V(uzC+;qg zGwG4$AjjHb_|KcT53(KY4chc0(ZUTy?XL8-5pHoo4H)&~t&15mOevjeROz*l27JUm zfwao8kFb!)I75(PD)WaxL!4?y$bQOMo8V^3kW$|v(&xr#ui<-V6tEM!{zz_in{>#f zhQgv{TU-N55|x;WGWP?3I=#<6``H3~lw22_d!Yko4!N=|tzz)a0hJT5l9fJM>QL1RsUBT$ufAA8ksK<54zo|xaQM(ZC z-CT!6->EaJ%Vz%}*z09I>>AOy^^qW4F?rLf=|MaLlsT0o5fwN`KS!au9)-7$gtv}F zaM%{SoxD60J@dpHDV|n8t3Cq3vvlK#2ktypc{4b?;=~GASwXx56RpKm8<##anr9Q z&mTd`gelNfshIdqqg*>ok=qW;$|Gby@~AS4!>BTiz)BhY6G~l>j=*na7Oc`#^Ba{A zK}NL5p@&DEF4l!Usk3OqfrVtYWg+qAoMJKJgXRy`P5)`s7UCnqXIRf9a^BEeY1kc% z#<-?R**KsYA>~APcZF0eTA!%J-wSNYbL}kVWaS*T(tz@7+p;=4bzMjq?nHP zUL%?QXW{>TM=mHaZ{+`@I>!DD*8kxo{!tRvZkF!u3byVZmQI%ckC5<;>4OUv!H~S7 zpSQ!57=M(Undz`Zr4Wl>2%HO}-TgC>_O)1md|XHt)3PzN zUlC<6%F{HbW#yhI+0SY!0M7PQ}(MXQt^V$yl|7e=P za28Y}XfUvYM56BkKz(=gBiukC-MQ5>PA()K)Dg}Z3AW|ndl9-$3aLH~688qzy%4d* zxv*}Z=E@qaAM(nw@~cITzH+M|xB1LNviWo?DpZu|5QAp+Zl}`Tywvs+MQdNxSO3n2 zc;q(p>1Y0)u%m#jBR_56$CWfO1W(8sUrv8Jl0XD3r-B_1u$DZQ7SVVJ7F>*}Ka54+Q&;0k(*cb}-AWj?wB8O)1=1RADfRE) zSI(=PlL^zi5B2|6+&7NYq-Oa}_Rx(uNXMqgHE7`jTMg{BULiA@`XPd5Jut#9ER)w= znkr#h5*Yzb<(F@Bhz)>o*QAjh1^IzY4mdC{Y1nrp@;;nd$pZ{+U4`N>36z2x0f z&g4q5_)IYF=u{gp3DFzTLL(cvB8^qYY-xv-Y>yb9^=67&ORb;CCPa3rjczxRkvObWf-=yg<)u zC}H)QlI|;X&(ABoXCfm~Wl+{!SCIDKK9nBkZJ0LOZBEX26mH$~Fs`Y;h7Sa(iA*jm zSAVk`PJDxOZ;LTy8tuv{G7c!g(^CbvG@96$(Nk@=rQ-{i5VL;E22m49QU;{~Cx7Du zpX))nIM1}394dotpj_N%-ayhBUfgEr`A&xloxo9R2Q&#=rIbng6hfBGnYUYc)L70ywE;$m-T_3dQ`37!Q{=!Br#|kcj7ZX-C1gg~ zuxolUfg^a5O1hXvPO{dE_UW>~gDpmMP2Yb!AgTx^^l* zXo{aj3GtQ-TX_ioxFb~DZu1_A@9%m5{72Mry3^^SQwdtJU#bUjC$k%DygXYHBLp#t z*F0ZUgn@L$9y5-nb-=2AtE&&HekqLK+vWC+0a>!mc7y?2vI7YwoX|7Sj}CynrUr|| zG3#~5)YAL5jc#dH_xAzmRf7p{d8ISz?1SEfpe<|zoL6uNf}KM~BVQ5R|Cprsi*~8K zN8#urYnIGr-TLz@LRpgAeVLJ~64w$HJ>8|(cygktV#&S=QzlffD2S}zy=q)iYtU?V zJgKa~mvix4Q|m}^@yHQKFzo1$+bfL({LQjC@EvbKZ;(ciXrPoQ7MTA7*ck8yLwy4# zi8^4Lzk{GkfE_>+e!)ZPRo{MfU34sPz~SpSqa16!--qVhhF2nu zTGJCuzCTH{>YrlmC=*3QhHH9`^(iVKJzBu_2@=RTnw~Y+;7$Q@j+6nqWUr=oDoKIx z??=+5vJa&L{COWtudOD^2XW&B%Alho@d+u4`N7gkWfk==h9jM4jnC+sAirhmYo^_y zCjddI3HFB6;p?yO###i-H}7Q5OxG)2>t;Rpr7n7s(-O2O)?YCHU0Wf`eK!pL@%^fe z-cU*4|Ir9ItFlWhf&144zySlJON@uaN~9UUPCOMw1Ume5U?D>g1!HyyjSpE4S*Sf>{60U9<1m;JJ`Y3=t6Z?ySBpQM0#eVYuT$#I9l7k^=j`D9|~wQ z?t_5aJQ?YvINqR3*%O4@tTe;iEH%TOqVZ7~!W%sh5-8gK2=o_`Borzmi-LXOq)kO0 zJunq6dH0bBC5{{WFo&C}@F5`9x-uDZ1v^jwY*-ag?6`l}DMUOPf<-RyNH zJp0l0#1a2F2%`%OA+CIe4XoIWQs_Jr7P(B&f(4N;fj-JNNlcfE^iW^oKD=7d#OHNo?YTi zh^9^kW1%KH#Za0ras|CSAc}+cAi0OkRgl#e&1T9HaH;)#-Dx9D<|y>_mr)+t--LRt zs@KsoF&tEg0ZFUB%B+9Sl{wkllcMVy0B&A-dkOk7$QJs;e!?--2LbqpgC;AG=CS6Sap-S1s;d@ zkQn|>VRAbk*QxjMfo8h!@VO{#;GcxNV2H^qEL2;G>MB5~N0!w-5bIFFn~kxdOJ@G4EZq2~1#1bQE*A=F(9Ht_HZO)1c zlXG=`ko7*~cR`lZ#^_D-!4KIA!l}Vs@(-zn@ECnwj?91_D*Q9%EGo%EV@~RVyMquu zlgyok@!f)8$9Ql~gQzo(=v^(u)@>_9X;=2n*-$vy0p@ECL(O9)DG(5z062Guz?wOd zhJhCtVNCnn4BFam9pt4_abrMdKW7K}NJ)FW(EJVQ4~G-hM7M0qcHGwk@i$B53FJzY6&TFfI$*n>+(eem zNEDZ;4T38&V0@F*urH8eP#ZK;T!^IfSOwT6eCCX%ek#mGQbw=m12xFY!izK7WKPfc z#n?IP6&SFW7xSqTOEB?Rk7FUxNiky1PVRXG@%hY3#A-T7Hwp5|Y1vUDZxi^dN@G+u zRy_>It2i$B{TIUZGIU6_kH(b%QL>i2n{TWJc6&=K2WFIEb> zS=+S+P$Wc8fLcTdI3rB3sK;rrNi}G28ei=P%HO3L` zDM)Fv!gLIHdq>qZMlLBM0OjKXtG2zsNU#7~=gAEn9%t3NzU%0HjHUn$%_RZ3%L4&Z zqyW=-v?C&vAFqUEmDkDx_(NzLhu1@>G%Ve?-ny|*Bmah-`>YI0>54^*CDfCC{Ze<> zRA^`eZ0BbeFuI#5^kn!7z*jl4297b%5?n%jKZdM~I@P@gIP_#*c4K-Zn1nN&Iqqw? z&e<5%h#0>q&EWOf!L8%@dA|Nvy^5du(6YU|ivh7xJ9QvGg>87RgFsHrmdK$zR~@H& zxTT{#e(t>j*CwoshXCI;d#LgUVcxvQCSzr3CFA5Wu-I&|+=UcrsD?)vv4tIo8A!{3bwJQKqaq@K2rn>)aPUe%tL8ag`E81)uEpyoL-O=&62*#$9 zq+wRy&IMP%JfI_nb>+1DHPq+mvftBvVE--}$^Gjnbcv?Ze375aEQ8x>7&q({0#RHi zG-et4cNht%E_dLXbA3`A_h|s&m;43+c!L98A|GDR%aZOxfX*I5LP%lk^NL)-cSZ3J zP?ps2+rYV9{t`eQ^Gs~9NwA7BpheANXe%x6C8lB9W(>X)G4*WHCLt*2HT}iDx6D6B zew8B%1^NW$IhZVCtH3nSOp9fH)0S~5hP=uZ!=%M-N`aK8xaiNTWsMTCKcT45PtF61 z*_>e5g*VVd4e2gG0~(6{65n$xlhJU?>yIxg?-pormT@VWuDH}Wz>T*;`=<@DpZ>17Ue;C6bG{`O?t=!#8QoHax&lO#_mgw3oc;-3xf_E_ay7TIzL z7Cn|V0Ik(QdFNp=_iJShC-X#kt$73YVu9h_gGig?{#>!Mxt3`n(Z*~f$T#13K`%*n zU``TQI)0{PK@y|EE$MNM2<_P=MkB7lH$1lEsK-0p z#?DS@h5MXwy`J~`7^fh7hzE3=G{_D8v*3(d5q6~VA~O-{ido52ht?Rq^EzO^q6YZm zlIj|bW>1J=P-+K2Q^`wls+S#V4&gJR3ns+s*20O$ zcv@HA^aoG`JAMFLcXZePviM97yZ^D}%`i+e?uj$3&b4BZf998{h9K1SxODOd$851O zjOANPALJ)fT(GrP&*P6W6g(?s^^%W%=oX0N$hA#w#(;gDx@?*D)x8D=SdRu!t{&T+ zTq3<;w?$gc3|tvL)|#(K`C`4(6(V9fKs76rCo7C`Dx6dK@+tt0`<`1_gS=Tiz1ba$ zn`4q@2BX`58vWX+Ae{@F7M8qF)GCM4yi{*DI8k5+v zem+@X>-<6C4e#B)-rBZKU&cZH)g_yJT15JTLrXV7QPIV(I%MexNS%{?3V9iXY$&(0ZAD;_|tEq0Y!#dh5qQQqYV zlo*a@)vK>jUq5=BSkb~IG+5~5i1w-%Hxa)Eq0#On?S3h1X3v{@S_#=P)mX5_$`dSKU2(K{4kk{Qq>I7LcA(pjhubeqg0=W)Web5p{xQdr`#rH$0m|a z2sulNkT!T}$5{s&Eez46EK}iBW~2$iP#p>lxMEVx{UOwf>vzm2Yjn1j_D}3|5me1(?V2yau3!dwD>SMQc}?@R*kfQUz_JxNWO0P) z;}*O*(OT!QIyQv+bY^57mC=6}TzbG2X6F5}36cB}(vHPpU-4V^W)!Vk=GrnH>cC?C<0fA0$|*C;=|5pN5@aBNS1?5+8m0Ng;5hSY0uMB%v` zHYVD^mL!Dfr5kg=2l{)G>e)ll9pdhdHC`aFW)J(hIM#Tl0i^Bmj@LWu3f0J0(Nmxt1wtM@-A#g*Dfx1%9zPv7Q)C|pHz#>Ng&U>8)sqav5{u%-p zNq=s)Cbi1-L(|F{lZ^JN=?@0V)~^2*F}G#=(#ZK2klV#NB{#6%-r z9mb#uT0qQZ9cdXqUEi#!8^Qba26ek#ElyN!?eK&sR4gTh9{MuUsjt>i#}P~~`j}8J zZAkRaIEXg3VCwv}Ri__~or^|~C5N+Ck*z4eH`jeJU3EF6=4Q1@6PIyxOm+%{R3|(P z0B^j~GI5K`bZUSP*;2f_S@xje)~VpG#h>x|-X!e|uE*}~bSPg7vrPNV>uXE9&`SGh z%MGs>7u4;!AV5#%upPiTzBZ*b*x9jP2g&1HJ1M~SGriP`?;&WUq_05r9SKe#OAY7SIR`w@{nam0&MlW-v?F@W;BD(6p&lX@o#_iJm8l{xXX7 zz3xJNV?k*Dc_UMR)$J`1n&zX;Y%IO&a|p**q2on3x~DyhTXRpB;$6F~GBj4%^`U}S zZuVEQYRf?KNwO+mB!b1i-WRFW5Q(wV_y<;Zh>ZpE(k$<~P{$>i5;HE)deT2D$c9dD zXchKGD9n37qf=euxN;YXPSe%;*)6+GS+dqN0J7ZX_@X9)uZnkF5T)zjMF2&9sAeZS z5<6D#_MRz}`xj1lD`b0^sG92~rGz?sQsi{L_3j+ds1^{bd2>lu+3)jyb5MfCZJQBh zGpOqA+!o#RTFpx`qd*8`_il>^5QIayn!7Jg7;N#!M;an6ll~1Lu;+awS5&$n%XPDu zqX1}-gq4gI9PJZHAsLz`Zxsz~)f0dHM)?diZ6<MKyDIuWe&om!CeD2ho(86-k`f~5N3jjPgD+|g?z`qotJh+PBNoM460DyBLw=?_lg=0r;D9N`zq14ae zTY*dxq&YO^iAA*EZ!B`i6ivfR-BiP!_H5@uFms3sXa&R%r!{=Eep!e4Albv^q7|G7 za1WN=3Y^fU9CCynh1np*A-lq+g340H_Ztl|;B4vc+9NA5jZpSO;g}O}qr^FKQ)Ry9 zNSG6k+<>T09=QDE5|Re!`~Yh($)rM=)37_$T05GgdPqh%m5C)r8PNH4dNf)1 z`ZV1xFuKA9?KPMd`=tK{@+I3h29xm$`J%U)tR6(66l|XB-RoCIAK0i$O5W|Si%~7-3RPSnd z2aJ7a#$RH=f3(1b@dcT~+6ShDYX zJ?GWo*f@5KD@izHGH=G^v|C$?v2d#<0xl7*RCLpD5V(K)12x65SJItuQjnlLdp6I> z+p}Dpnf~q>5#GmbSs4LnPC5Happ2Ip*Cl@9dp^y{@1!F&DPV zDBc?5%Wlh_y;I(Y^#mK{m6lB_-#RJbFIj%(!LG{4g{s|T9mk%W!$NC=@y&1C0VqHE zL`6Twu}MkHeSWHlkH=cf;wLAc+GBIlkfIT7tEQn*JB_FDZ0Erpb7`gLWZed*euA$D_dRN098RM7IE~8C6&ua&ow50*FAo}% z3#{z?nvNi)uxg)Al=2&6yXZM>2L2}dq2ug@C#$dJ6+REoE`YbUL5uH!C2ljr^n`~ON;f?`h9;~Eo--q1@5<~End1= zDoYz1rq1@T)As11^AxeSa@+5hv$m0pJsEbH!;=bRLWpp1ur#!&obInWXgRHuF<07 z+HE>CVWIXTS_Mzhv9V6U3dj;1h>b60@iSj~Ju9t=JR&LkTfu;@XMf~L%Z0+Vbo_uw zX(!?f&v@Bcb%@21CN2A^T7QmI;)v2ORCCCwCCgxENodHa$YCBGy>cfUVL!P)ijekb ztTVVrfeVyotb(yL>h)x%)ssGd6`WZ2mQ(YZYl}SSF%&2=J$2KuS%C$hedX~1wX`w{ z^{K#bfE!GQt6;N~Z#K%Chq%wEq)C~P##UlCygBtr7vTovPWl13#ynobb9Vbh(75pw zP|_A|KOm=2;yrag5{^QWXfp#;vFbrSbXFE<&C{sk#H<#rDoprt{*vbHrKEiMg0mZ` z$v@L7P5vVpS87HhA*P!YXaDsT9BBH=%S{DgNCRx zwcUNOk==Ev479SEIvWcu!xwH77qzfjc}~_PyE1aLDd#nObAU!FClIfG$*;B|#kup$ z8on7hswa4_{K+*X%w_lA1uN!=dZ43~EBccp^KK+Nl!`Yzs{1=Nds2GKZaurCcbG>< zQZ;*WoK;@v{UKV8%;`Cu^HJU^#*FuB#X}tsQ70Mg?dVmDX#5MuxNo>o{;r@mm|;pB zLxnnPy9YT6>6 zWNSB~>%la%S>2l@#y;A@v){c|sF)+%883Okc4!8MKLI299xLA+H^-Yk(!`1Y)O}?6 zLqeI5bixx`s;P$t0uwJJJDMcf5~msdxFeE14nIiol41=`ith~PczYX()#<= znI>TT-;A-^@urnrqdL~)zm#gT;pnHMdoic>5l?mB z%I^6;+xvS}UIax)m|s3f<>Sg{H9j%@CwhTc=Mw}M(Vpayt+p$)ynZt8*FkMi`ZL5Q z=%KlrN=x0$5EuDZ^ zUckc!>!QC(I=olD40)x~Y|S|^=rAkG@N4RSo?SaTkosjqV%zpyxV33`_SBi!TueZ( zv4J;U$GtOqCPuzlnZHJfPT)_z$Az1?tyRoP*(9CD9=9Y3AG?_1g%?R)rzVXdjuyqI zkG4}zw4&RCnC0Q*@dR(Me!CXWU%CNzMSLQ%4?K7ai=58iCqCqc>OCJah?>yF-J*$g zH^ph$S5VGcT!j!kcx+dA2cz?Q9IN~U9%%0q6fP+f4=q{pk(uz#qoX?^hKptTMpZRH z%cJqDg0h{n#%n1G66!6aHymz>=i-)N!mo9b7P((b;u$-Q=N57Q=s5kJ0yki-#eGI> zm|@)BxNHExjhXz1SB;?Dh(X(a=ICpFFe2G8D$m`*-j;XJki@Y@=?J=OlAEe_c{wE! zH<(fn=Q)j|M4gLjqpALZZzKafczOm({yA+#i`SVNQcH=(YDh&@s|63x z%QN}r!mOuAL?ma7F6*q)Uk@B@hv&O1`o()FC3|am*e}&E^6F7O=CKN!ZZU*1wGNiB zz{stUsmJ!U^9N67Xa7fu1Tq>mT#PBvin{=Sri>(d)01%Id#Tis6T?Zz)?FlxL4srO zKS@?-4#f9zCc$vug z6)qfCcu$5dg_{COOcxGPsmTjbEAC^A(?T_}v0@fOC2f@XsLu@3i3>})fU@VQN+DR9aZa0ZeyyI7Rde0_K*#j|8-ditoeTQ3YWiM6(B8Kaa_8> zIpd~u24>3{=?v7ZW5GcZ@FQkSlaL+=>fhd_N1mtU1nhJLW}Nkg-42WmLVb9grqq!c z-nE<~-S!kZha?Bm5pj*%WrRF}hi}NC+tBCLBQkaUI-K#!P{!_4;Xn4U`^ih@!Gzls z#CL3VN|D%ctkwZJ!w%MzX5NoPvI{RZvMq&gP-S90m6*0WemEur)B(SijvV15$fnxGnLYQGGcO(@I&%RP334 z8oFoF=N8T52xV}|-08#1y-%yyR@N3AuzcG%kY>>f(rDloG~o4JexlGkP{9-FVF1&$ zN&K|}Z3FcFCM2iO2!Y_WiPTTVtJ4l5DjX5Lg1xVZ#Vk5P@on%tEe&c? zn*I&m-<*FdSwUZklXr>-EY1t;%WlH?q0?4u62BX6v^jSwJ+hm!xIUJ$D6-64v9K>B zB@d}A{}E=p;xaMindJtBV2AFBXm(Q%99k|ygPd6#_{gxP2if^pn?RLAf zqMz1t#E)Ns%vXtbuK>P%ily&DZTtCO<|L;K`;k9?YAom()w%tcG8&)!>7iu5ja%XP zfLRrM26wv6^IY3w`2%nLy#?b>$%XSXfZDf0{iN zwR0jY@~mb9et=~Qi{MkJH<|Pe<4I1mmN!#9lVOG?2Tw9B4D_W0t~NjcB+>ezCf{r- z#=Yo`?lzX-Grx7tIUKG@v#0h2M_s$2bYPPeJdwx!xpUn|#dg3}MP2nX`S3HXf2#+c z2>ifBo;8yQKs>A!n`kBN_d_|-Chw`0R=AQJ6bPqTM&?5v*o@o#aMgK5F*8ST5dbIY zLEipAszclIg2)mKAI3hR)cLS;5N4jI-);-Dnyvg{hO*A!8)FofYHvgR5x)5&m3Vla zcwTwN`wzfxKIm}-cN(Z5>?t6ezS$4FGK>W|&#fUfx$m>lce^?brTz}|?Ta1oxG^t! zQrA}pi24ajx)J3We0|#rQaHxs5r_p7o}SgnbHr02$5Zg6Edo?>01aL5NiY8e4!!S zv*~mPoA_W-`61Gtds4h>+n{1#=coKIWVPy+?hRSqLnTU>3D9xJoA{!a-ao)~XDl`5 zKOBp%{JgJOf>uI<@w(Q8CJr+oaHZ*;VAzVhvRWl%A@kS zNJ0sAbGe9W4&iYErb`3XA9w zyZ2i#{raw#n^*IKP7@I9|Ee4-$^Dz?u5KexrZ>p3)jacqQ42<-6~+YkiPI8V&4$$- z@k!bpx(=BE{u}@1U<&@*IuHySNHyMK_8zx=V6}2KOKn1%voGyAYhV;nQQ(>W#e`?9 zda{5a_!j#KTX!reP%4$`{uTVVmH%k0vha=#*V!v}{52&4F2PQQCEoWD8$P6RLvEd# zxp%%H1XdFMxiVUXi%JcIKAFzDj9mV~TTrK_6h%HR+EcTL9|EN&z+ELV~}lD zZnz*@G{Lp$1x!gRu0#|HGJF=&SypVdDV~8O(p^ zvn+fkwi5oCv;|?oz*znVgRYOTu>my&@;@*dQ;_Ds|HERw`Wg0ZfM%rfv>*)s=|nGH$SW^Z|@gTg;|NY&0#C%TXbT$+C^stA zGTR0#n6G&CCiL|yFdNWWrDc|Xe|Pk>*_Hm3xi>kX-+h~lZ46yU_=U7nk3xjJH_3K- zE%9A>?E7vO0<7}Ql)jjcJ&rT{4)B64XPDoDV;dJY%9Sa^drT+N9g*UNiD+|j!0&n6 z58y-WzC}C?<0CZ9PrUy(tluZ)2>I?ho+W4R1-vo$=&$s^GtM;e(GI$)f5MUS&GiY2 z5c;t7%8%*#=OfGWLG0zhsIFJC+8&JI)Rp(zy5HL3&v?_u){pF@T_onnhrqM|*5Bv;O8XIUHG^-Ln7(+fP@OF{x1V%$@FWkkdhUl2%|QsPyqqV(@nRz~ir zf__O(E+2`hY->ETp4}#2$)Q|E$Rgd38u1e%WHC;5Pn+kmu=b9~bRl0G|B*|_6>Ipk;rtbg+m^>xGJw1S@!J}kXZ_j{}_CllqU6UOYl$Yy%vyD#U z<@?3H;4qd5Z7Qf70jw-%uOZ&|aPCoQIKO}(Wl+g0eFOfVI<5k& zif4<1fV6aXhk}5#ba#VvcS)DPm5{uEa4G3-kVcU1F6oqzZV*tycj5hmtMARn{n-8H z_d9du?3vj!yF2HEA_sA~FBGc+t1dp8OyzlkI`ihhE*nbto+|PU^0#;Fh=Xpmw(?aUy3~t4aI@f#ZDRU_# zN&o`0k0bS;#rv&6)(q}dlKY>Z=CB$RlozHlDoa}w5_eO>D$c(jiX92E`o7ym*{7Zo z_l44PKSoDc6+wrvg-z4vIRBh9rOXX8EFkk_ZWj{FiTM zQW3RE5l89Qo@d8MFOr)E&#Gl!D>SfYf2HG;kZx1dlJiu1p0iEKuG2A+cy-DcgnEq( zFu#r=kQeZY@t?7ab<)D1w^tZ@A;8KJL4fh4l(^7<0pG#^{AG4a+iRTb$X6}!G|S_* z>Q{pmZTZ-Ps}n=sj$XNjqbA!!6pHgE`~amR$!mr{!KatVbmF)s6xZr)%SRXJx0zql zFB1YqVIfI^$ug0u_QZSy20{gPwC__QIN9W6!gq=hoR zt=Yw|S7PdM{2VRftfaf*k8t65G~$A4>7_@rxwExzeOl*v_8Y&yW*G9-15P|=ni3!# zFqu5WmF1Y^V@*+417ApWd2zuNZG_<#9kcz#NsdbUG^}C|op`zY?lb>V1!gZqK(a}| zOXB2^<@%Z@ipkvsw+a}_mgI>p=Gtoq&4J4ZKPh{4+ya~hVHpjKhsr$WhU-vBGHg(^ zA9vMYT3(!nk%^VDov>|OErb^z8KIlgT9oIP)&c1IPEinbR;j?>=`Q-BEv$Ypcz*Uq zv#%_R#@qhl23X)ow!5_pV7=+L0tg|Kwg!kbg%$AHQvG}%tS|185UeliQWxADywySK z#XrVR>P1DlkYPo#Lds;mGspg%V$o-dt`9n^L0R!>h8gtu)}tMXwP^j4hTCpx-u5$vH&F*SF9+7SJ z(J)=is|rfr58P(#BPO|;5*o+sQIlrXgV~cyIwprTp-naCOZ?|cP1uQBd{eW@yZb|^ zBIS!q^OlEpm~WDwXSoV_v;ex!1=^O}V=-FXLieIpwfKS)*WB^q$38_g&I$=a*O|b% zDY>}EOxQQ{^LN%qmA!ecALWzS=9|(1&HD?Ag18fIAqsD6PLycArbEiG zPzkqhjHaXU#26X>Ec;2R*|sjp&^~sC7@0VeXMn2z_zGLn#+dL+9R>i?#u!gR!GeaE zSWB{RGwEXhS_vJAZI=wuz!*tq6Sp7N`vWdaoQxk7t5KgDz8IrXmPhy2dfK)?^N`MJ zbVsfs&+stDf9{{rOQyZaaeA|!b7%xS`(bl7aVY~ z!XWpOwJ&;1xOp(A^rrPzNHXhP+0U=JNgjeC6@x}RG~`qVm5TKML|nf}kcey`wKF9g zC3SLs725|pC8bC9P~6Ac$i0qVGeEv89wJCeag#rlj&jszCh>z9cuA>nNOGtGt9vD6 zeo|@I<5N^q!iJ}zS8qSR@r!SDov4G|h?&Na8!l~n8|2}C;;K-z zrK70Xs&(QMFY{AbFRaUCy=_fXUTY?ZF7#I{UF3cl)7@VrQzLK03(CmSz{`w~sS=_l z>>A;CYplhM+l()E5-_@rTsrph#A)YZ)kBku8(Z(Xc)Fu*0HdhSribx&%R)NjPFwrSA2PYHf{X}3+Cvt9$^jNG4 z5h|WMoR!TUH9`BRDebTv%QfP%-hjKoe1fvB?5p$}lG`V)>C#eIwBxZfS}D%wX+A&B zmn;rH2>!a=M}s=drdYugz&#EP43|3n78$6%5LX`bCgnOd{Xn+&>kGtms+T}lfGvs% zmX7xiV{`+VBMPn%_>RQZS1B_a1Cb#g>u<|Kf+9<828Tnr#4^;Stx`VM^7RJ^ zc@8`I8jT2R^)cCny`oGqOjQmL3SiCbyV#axmAOsOFbhVgIa;hJjk5BY6QxCRl0NO2 zbkvsKq(*g^wsGRY@gQT8_Q0yr*yu&I(;{{6O0QKp$!IP17fM||3>c1!L6!?^&lpba zvf&teN-C?089C?<5;VeT(?ZdwvvLxPQ;eamx$(fXtU@P_fUs6JwVeE&F+i(=(TPbRWbfnHiDxxaQQ z^_${&@$|XC4>{~{C*Kf$R0fo^DCn=(nl^??2UUD=Gi!_>AgD^jIF10iN8=rr0_n&j zcy4pvW`$q^vchIS%H7Qf^4-vBVFkSfA_+zr67JWvz(XNNhao-4K2_mvNWM9dc?a+Ht$;XB%v^P8sEk;5*Tvn;S9Z=>S~zdBk1d?84%5 z?0M%r@1V+=VouP3F0~#SRUQKoF3$Lm zYo-!&>Zfu?Sp@?0nTOQ+mxJcY7ccfiy_|QL$8O4O>KY2RX=*C!d(d~{!cfwGxT>@e z99v)T$Oo11woI5t1;+sT&b&8+D4QTsj?%6Z z!%nR|c|5fy7WU+^yS^8yNQP_JTZJ!&Z0+mOREbvFHk1yEMn5g60bDXz^dfUWG_;u2 zrC*eXFx8tT3m*e0;Kx~m2sq0~M9nWTY+OFI9zAN-Y0p6?c4TQFMu78e_ekljFacgw zoW95lISGFB#2+L=PtNCfB(Xat*wURI4c`*}6Db!vHiE^>IJ)wP;v0qhr5oa`NqZNS zCWTmd$k=m*t#-|J4udQ>;Fn;-M~C&t-{z0MZ9AX9aP4|l)`}hLy`J`Sjt_MX7=Gkv zze>dgsOuhIe=1Fv7C=+kYbS$TafvL)jllmhyH;i3R5rOeeiGaM^HqNf6#$e>0KT7VLL zpbj~;(0C5TXx2=AWPvfk?8f-j%?Xyrw$6YonPq;U^oQ-U(BR=S#k1h*o5+&hO0xtx zI;>RwV*by|2flCC1#fS^b3r{{o2RcelIbE+t~M%y(P3TmBWPsE)%x*?w1e2b(*f&s zU(Y14XWTPAni{+}|4?V#vUVybLl|1bvFe^i5% zB|)L{Az#5hb{96au2jacoBlaH_YA^Z<>`mU(oMPOz9b3rPHo)@0dpo=_E^whK#>wT@P>rG6}(20}G6 z4|>LEnuK0>c?DdPOaHe>|4h@j+%Uz317oc`(q-x-`-)}#a;Gb%{i%b$fa#xzG)_wM z?PqXv!})v8y+m6C1A!or;n zhb*`aWf#q#nMfy221Fa8!mogYjNGy}dukNNM{~SL=-FwYJ-NqrG=P>4uL^o3c6?i2 zzS8{XwqYXrY>6EB>g60fCk9i|mFnt!A@#&`VO9GUyCG&tozx85t(9F_uCEN~TDs>i zx6!DWwH|YZedgSmrygtc5&YGMD7my*w#PgDX+6s#K?3jF4StUI+oa{ONc8FO!h9u_ zkx|Yo?0rRanHwO7B08YVYT}HI5{dcHKqA;bct(Vx=*Zia?>n+cz`*Dn%js5ni*Ht) zo9X4kJB0N4ZNavJrY$4pm!W2fn#0P3xm~i=Qe(#WthbG`10d;UPdNC{r~(HB(YI7~ zJw}v*B3f(Olf>UoyyC`Ly$a3aRutw+qDM(zJ|@TyQK|1i)OH0_cB3k}I;AvBJG8qx z#TCP5=8ackMm05NMS8srR*fu9EBX+u?)p--gOTHgbPA-9IQ=8mC{l^aj#p(DLkDqU z1KH(m&kKP;5_@vE{3Kqj`N2M6c!L*o`K+tFKfcIo@`=(VFL8A5xC#cx$M0fJ4LL*z zO0qQteqW|YIyle)v+`2w zGcvbwp*ORk!sZ?!p3M@87MJdb7LF0?AG+WcDB-NX;n|B|-0tv;K9zp!%zc>WHoiP? zAmrLTI}nQ76st;;sz+{6JRDiybzmN8G~9QgBpQWo{j0*y5&&xUa)0x^d1e9a>Rc3A z@P+)1u63F&-}?n((C0DAdLMfy=_qMYW_k`BFMqMtSti~uJ|1dlBZ)m!zs|ad@)g-X z2XmS?`K>7KHXh)N@Qls7pcI4y;=;U$Rk=V=_VRn!B0m z!}-*aJYa4m+f0o~$7hRpF;%t*rvf@Z@Gp)n;~8K7ZLSAp7_B}GJlpDlFb~hI({~Nd+Ap} zc0pqGPQ&l_JVe{d$KuL7054O|-T}I=o`@sqy>3l)K9F^d3g|m(Lcu@hZvB6Gl=yFxA1mps0Dxm;8F1 zu%9+SAjE#6+o=9c+s9Ae9NcY(qKCdob>$Hsvc;y&D|y93h4;|q*aGM!sUDjz8w&0l zgb2^*MylD8jNqfMOc&X(PnOr9^`PVegkPAxaoRg^C_1aXofu`0jr?vSRcaPtm&N9_ zG(i@^rP9>Cs!~rCXWHJ%ge6%nN8DlDyPU&T5z0iu-kvFLLuAqdoE)!$)|#ObnZ4td*DEPVfegoN%pyK8Z$pd=WRI&g2bEKlp6Np= zDH=Ikjbv@LK)aj*Q||X@qHGjlZ5<;MWQtt#lLK>qF-mHGI5s_nDG>=N)9n3JB?~)D zp1DNHq^J2{QKKDpwhY_?jbb*b+(L&B^~uMA4F%m(9?UZsr%AavuAH5-774HOgl^|k zOwac_i;3%ST1*;48pX`R(BZc#9wGc*X|2A2fWUxWf$r1-iwFtbOvaZULbyK$6@QCP z(5>+i9=a&d`10YC=*rUVhaO8UUZPSDcF0ojJ_@dThg2GT46<^<1lTBkQNs6Cm>yH+ z#b3)BL=I8aFpP!vR}yoOs4|5H5nu|&j}69@(b!2|6WpRVU%~;YgGO%YSKmxMrc1^K zm2Nii9e!&}IG>)3N{5p1cuEz)LlAJy`qmQ>nN93je~wN}`78gK0aICY=TsHBMX41PI|dr7P9z>}RfmEF1+e!`dtc zEPD4y;Ny2=7dI+a2>f2Z2kn=0)to25g(7433V2U!r$-X|M40u=DBXePvu1XBkym*w%PRP0MSZ8w`V zwohl;h?1I;_YG$Nk*Hdn-c_rYd22d;uEuUXX+UB6M4=BxjAhou2`2P67iYg*E6SZw zvYWIe1BeB2CmMnX0);I}f|0Fz@Fxa^TD~)9;ssR9OWV+|L6hD(%#N|@!If#4TK?5MTM&TCcwK7~IRa1?<6O?9@nCgS!^IV%qR zE$afjfvB~z>2+KR&9-jpOVQOwt8{LW>+WZIB6F#Sn06s}QjX0n+!SfT0!@*eA+U6; zl%uJznIx_>XT;*)CSdq%Eh@t##T*CnJ%G}cshQ#O7&PW?^q=XJ-E49wTBJsX^^6VE zZY`7)Ue_D*%Amxrw0N(ZrYcYrq3!CWAEP^@T49bHrJV6Sk9;mKMNf4{kx9{|Hf_|03HMC;253%pD_UJ z#s$rrAp^FxGfuJ%YeFCF7aQMM>~CeZ@>`|JINrpOIILyUeFt11R<2X_@+5tpmqMmds~YF;F|xX)pa| zZioMXGq>`*G2S3yB)0jpi()+uNvs&AsC0?(P$yPUz7LOv7klA*XA(FCy}!Ca?!x)?Ud-WP4=v;H@hK#|0yL7Q6%1_fgX1WQJzbl~@) zfM4et##UR!NTH6~;V6l1y!^|D;s44uU1eP-|8O3!Qgda82t`_enV1iq-0bZz{KNB~ zh1U>#{*Zo%L6K0?_wXF_s!5#iF5NZ4UkZRYuHp+Ie&gn*~AOpL>WBd1S?4 zkhFjDYl8`3VRr@ozyF{>S4|{<|I-3E&U#Q%z{htfw|^IY2l-nkaOn1+w1SWC7#2=O zrnYAPp9o55Mg>nFP*A(~Z*yCk;piS{bm*m>a0pgq65L^?JJdgg6dFX)i35swL5Tjl zQlOD$d@x7zF&IGtLTEvKC=nvl_dn9^4*1~j@X*vC>lTuSjDPbvLqSnMFj5i04El#y zh@4#z*j>Ck=_3C-h1c&r_$Ngc*rqQa#LVM^#o&PKTWKCP`%gL(aJM1N6h?NB$7&^e zh=<5>0wJH3@*Yp$LHrQExu@w|1jfySf0Ph-GNyZcJ}la^-#hW|F4Nyhh|Kq-w;k9I z8~J@#&cE%DaQuab2k*~8e#n9Nq~Koy_y{0%&k1S6Kz`s)p!AMA*T9s$uN>`Qd??KL z((36JIGiKAOWqA3j9C6JJSy9NlfeJpSBTFNAgEGm_f*C)lm#~e*}#Y`2)djYw9`!tVNdVDJA0bhgDao@A?@Gih`(RhuGja{8a+_{Ah8*k zMdg8Y-2(q0uR@tC$f$zq1?&HI1&LaO3x4oYwjVrYLH0Gt?T!Z$9VUZN9oT=TI*ZqR z5)LzjeD7eg41+6Rmm_(N-mbut9O((k?jn0`ix)-ihST7MjPU#ZkX0a3Zwb?>FX z`^qL`qCclvjC;E?M*WvQNbyj4h$Rw)E+jF3;qO*V=znw~#a4GDAAI%mz-HuzAU=)z zhnVh*@uxcb_qL=@_#4Ho>f&T&Z}Gpc6h!z6(F}6Z-vU6uZlZ^MV#2ZXhX*_5XRy)O zAUNMr?m5YI|3j^ndn5Cu-y_I-sUAvvms^czfe8iG&G@@>dS!v}l%PZ4<3B8<<6)l| z3%-r_VEj&^sR1DrQU0H43Y6N2(+Jj{96WBHL1=%|2&OUrX;9t1I}dHtJNpla3*1-$ delta 23839 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 \(.*\)$'` + 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="" + +# 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, switch paths to Windows format before running java +if $cygwin ; 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=$((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" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@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 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= + +@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 init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +: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 %CMD_LINE_ARGS% + +: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/oai-client/build.gradle b/oai-client/build.gradle index 9d56296..0e6cf90 100644 --- a/oai-client/build.gradle +++ b/oai-client/build.gradle @@ -4,30 +4,18 @@ configurations { dependencies { compile project(':oai-common') - compile "org.xbib.helianthus:helianthus-client:1.0.3" - if ('os x' == org.gradle.internal.os.OperatingSystem.current().getFamilyName()) { - testCompile "io.netty:netty-tcnative:${versions.tcnative}:osx-x86_64" - } - if ('linux' == org.gradle.internal.os.OperatingSystem.current().getFamilyName()) { - if (new File("/etc/redhat-release").exists()) { - // use this for linking to libssl.so.10 (RHEL/Fedora/CentOS) - testCompile "io.netty:netty-tcnative:${versions.tcnative}:linux-x86_64-fedora" - } else { - // use this for linking to libssl.so.1.0.0 - testCompile "io.netty:netty-tcnative:${versions.tcnative}:linux-x86_64" - } - } - alpnboot "org.mortbay.jetty.alpn:alpn-boot:${versions.alpnboot}" + compile "org.xbib:marc:${project.property('xbib-marc.version')}" + compile "org.xbib.helianthus:helianthus-client:${project.property('helianthus.version')}" + compile "io.netty:netty-tcnative-boringssl-static:${project.property('tcnative.version')}" + testCompile "org.xbib:bibliographic-character-sets:${project.property('xbib-bibliographic-character-sets.version')}" + alpnagent "org.mortbay.jetty.alpn:jetty-alpn-agent:${project.property('alpnagent.version')}" } - test { + jvmArgs "-javaagent:" + configurations.alpnagent.asPath testLogging { showStandardStreams = true exceptionFormat = 'full' } - // note: bootstrapClasspath does not use /p (or /a) - jvmArgs "-Xbootclasspath/p:" + configurations.alpnboot.asPath systemProperty 'java.util.logging.manager', 'org.apache.logging.log4j.jul.LogManager' - systemProperty 'io.netty.leakDetection.level', 'advanced' } diff --git a/oai-client/src/main/java/org/xbib/oai/client/ClientOAIRequest.java b/oai-client/src/main/java/org/xbib/oai/client/AbstractOAIRequest.java similarity index 88% rename from oai-client/src/main/java/org/xbib/oai/client/ClientOAIRequest.java rename to oai-client/src/main/java/org/xbib/oai/client/AbstractOAIRequest.java index 3e06686..b9d7caf 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/ClientOAIRequest.java +++ b/oai-client/src/main/java/org/xbib/oai/client/AbstractOAIRequest.java @@ -17,9 +17,9 @@ import java.util.logging.Logger; /** * Client OAI request. */ -public class ClientOAIRequest implements OAIRequest { +public abstract class AbstractOAIRequest implements OAIRequest { - private static final Logger logger = Logger.getLogger(ClientOAIRequest.class.getName()); + private static final Logger logger = Logger.getLogger(AbstractOAIRequest.class.getName()); private URIBuilder uriBuilder; @@ -37,7 +37,7 @@ public class ClientOAIRequest implements OAIRequest { private boolean retry; - protected ClientOAIRequest() { + protected AbstractOAIRequest() { uriBuilder = new URIBuilder(); } @@ -135,35 +135,35 @@ public class ClientOAIRequest implements OAIRequest { return retry; } - class GetRecord extends ClientOAIRequest { + class GetRecord extends AbstractOAIRequest { public GetRecord() { addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.GET_RECORD); } } - class Identify extends ClientOAIRequest { + class Identify extends AbstractOAIRequest { public Identify() { addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.IDENTIFY); } } - class ListIdentifiers extends ClientOAIRequest { + class ListIdentifiers extends AbstractOAIRequest { public ListIdentifiers() { addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_IDENTIFIERS); } } - class ListMetadataFormats extends ClientOAIRequest { + class ListMetadataFormats extends AbstractOAIRequest { public ListMetadataFormats() { addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_METADATA_FORMATS); } } - class ListRecordsRequest extends ClientOAIRequest { + class ListRecordsRequest extends AbstractOAIRequest { public ListRecordsRequest() { addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_RECORDS); @@ -171,7 +171,7 @@ public class ClientOAIRequest implements OAIRequest { } - class ListSetsRequest extends ClientOAIRequest { + class ListSetsRequest extends AbstractOAIRequest { public ListSetsRequest() { addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_SETS); diff --git a/oai-client/src/main/java/org/xbib/oai/client/ClientOAIResponse.java b/oai-client/src/main/java/org/xbib/oai/client/AbstractOAIResponse.java similarity index 55% rename from oai-client/src/main/java/org/xbib/oai/client/ClientOAIResponse.java rename to oai-client/src/main/java/org/xbib/oai/client/AbstractOAIResponse.java index e3b6a35..8cc4d54 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/ClientOAIResponse.java +++ b/oai-client/src/main/java/org/xbib/oai/client/AbstractOAIResponse.java @@ -9,7 +9,7 @@ import java.io.Writer; /** * Default OAI response. */ -public interface ClientOAIResponse extends OAIResponse { +public abstract class AbstractOAIResponse implements OAIResponse { - void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException; + public abstract void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException; } diff --git a/oai-client/src/main/java/org/xbib/oai/client/DefaultOAIClient.java b/oai-client/src/main/java/org/xbib/oai/client/OAIClient.java similarity index 66% rename from oai-client/src/main/java/org/xbib/oai/client/DefaultOAIClient.java rename to oai-client/src/main/java/org/xbib/oai/client/OAIClient.java index 59c242e..2e32659 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/DefaultOAIClient.java +++ b/oai-client/src/main/java/org/xbib/oai/client/OAIClient.java @@ -16,9 +16,9 @@ import java.net.URL; import java.time.Duration; /** - * Default OAI client. + * OAI client. */ -public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { +public class OAIClient implements AutoCloseable { private HttpClient client; @@ -26,13 +26,11 @@ public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { private URL url; - @Override - public DefaultOAIClient setURL(URL url) throws URISyntaxException { + public OAIClient setURL(URL url) throws URISyntaxException { return setURL(url, false); } - @Override - public DefaultOAIClient setURL(URL url, boolean trustAlways) throws URISyntaxException { + public OAIClient setURL(URL url, boolean trustAlways) throws URISyntaxException { this.url = url; this.clientFactory = ClientFactory.DEFAULT; this.client = new ClientBuilder("none+" + url.toURI()) @@ -42,64 +40,103 @@ public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { return this; } - @Override public URL getURL() { return url; } - @Override public HttpClient getHttpClient() { return client; } - @Override public ClientFactory getFactory() { return clientFactory; } - @Override + /** + * This verb is used to retrieve information about a repository. + * Some of the information returned is required as part of the OAI-PMH. + * Repositories may also employ the Identify verb to return additional + * descriptive information. + * @return identify request + */ public IdentifyRequest newIdentifyRequest() { IdentifyRequest request = new IdentifyRequest(); request.setURL(url); return request; } - @Override + /** + * This verb is used to retrieve the metadata formats available + * from a repository. An optional argument restricts the request + * to the formats available for a specific item. + * @return list metadata formats request + */ public ListMetadataFormatsRequest newListMetadataFormatsRequest() { ListMetadataFormatsRequest request = new ListMetadataFormatsRequest(); request.setURL(getURL()); return request; } - @Override + /** + * This verb is used to retrieve the set structure of a repository, + * useful for selective harvesting. + * @return list sets request + */ public ListSetsRequest newListSetsRequest() { ListSetsRequest request = new ListSetsRequest(); request.setURL(getURL()); return request; } - @Override + /** + * This verb is an abbreviated form of ListRecords, retrieving only + * headers rather than records. Optional arguments permit selective + * harvesting of headers based on set membership and/or datestamp. + * Depending on the repository's support for deletions, a returned + * header may have a status attribute of "deleted" if a record + * matching the arguments specified in the request has been deleted. + * @return list identifiers request + * + */ public ListIdentifiersRequest newListIdentifiersRequest() { ListIdentifiersRequest request = new ListIdentifiersRequest(); request.setURL(getURL()); return request; } - @Override + /** + * This verb is used to retrieve an individual metadata record from + * a repository. Required arguments specify the identifier of the item + * from which the record is requested and the format of the metadata + * that should be included in the record. Depending on the level at + * which a repository tracks deletions, a header with a "deleted" value + * for the status attribute may be returned, in case the metadata format + * specified by the metadataPrefix is no longer available from the + * repository or from the specified item. + * @return get record request + */ public GetRecordRequest newGetRecordRequest() { GetRecordRequest request = new GetRecordRequest(); request.setURL(getURL()); return request; } - @Override + /** + * This verb is used to harvest records from a repository. + * Optional arguments permit selective harvesting of records based on + * set membership and/or datestamp. Depending on the repository's + * support for deletions, a returned header may have a status + * attribute of "deleted" if a record matching the arguments + * specified in the request has been deleted. No metadata + * will be present for records with deleted status. + * @return list records request + */ public ListRecordsRequest newListRecordsRequest() { ListRecordsRequest request = new ListRecordsRequest(); request.setURL(getURL()); return request; } - @Override public IdentifyRequest resume(IdentifyRequest request, ResumptionToken token) { if (request.isRetry()) { request.setRetry(false); @@ -113,7 +150,6 @@ public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { return nextRequest; } - @Override public ListRecordsRequest resume(ListRecordsRequest request, ResumptionToken token) { if (request.isRetry()) { request.setRetry(false); @@ -127,7 +163,6 @@ public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { return nextRequest; } - @Override public ListIdentifiersRequest resume(ListIdentifiersRequest request, ResumptionToken token) { if (request.isRetry()) { request.setRetry(false); @@ -141,7 +176,6 @@ public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { return nextRequest; } - @Override public ListMetadataFormatsRequest resume(ListMetadataFormatsRequest request, ResumptionToken token) { if (request.isRetry()) { request.setRetry(false); @@ -155,7 +189,6 @@ public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { return nextRequest; } - @Override public ListSetsRequest resume(ListSetsRequest request, ResumptionToken token) { if (request.isRetry()) { request.setRetry(false); @@ -169,7 +202,6 @@ public class DefaultOAIClient implements OAIClientMethods, AutoCloseable { return nextRequest; } - @Override public GetRecordRequest resume(GetRecordRequest request, ResumptionToken token) { if (request.isRetry()) { request.setRetry(false); diff --git a/oai-client/src/main/java/org/xbib/oai/client/OAIClientMethods.java b/oai-client/src/main/java/org/xbib/oai/client/OAIClientMethods.java deleted file mode 100644 index 0018980..0000000 --- a/oai-client/src/main/java/org/xbib/oai/client/OAIClientMethods.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.xbib.oai.client; - -import org.xbib.helianthus.client.ClientFactory; -import org.xbib.helianthus.client.http.HttpClient; -import org.xbib.oai.client.getrecord.GetRecordRequest; -import org.xbib.oai.client.identify.IdentifyRequest; -import org.xbib.oai.client.listidentifiers.ListIdentifiersRequest; -import org.xbib.oai.client.listmetadataformats.ListMetadataFormatsRequest; -import org.xbib.oai.client.listrecords.ListRecordsRequest; -import org.xbib.oai.client.listsets.ListSetsRequest; -import org.xbib.oai.util.ResumptionToken; - -import java.net.URISyntaxException; -import java.net.URL; - -/** - * OAI client API. - * - */ -public interface OAIClientMethods { - - OAIClientMethods setURL(URL uri, boolean trustAlways) throws URISyntaxException; - - OAIClientMethods setURL(URL uri) throws URISyntaxException; - - URL getURL(); - - HttpClient getHttpClient(); - - ClientFactory getFactory(); - - /** - * This verb is used to retrieve information about a repository. - * Some of the information returned is required as part of the OAI-PMH. - * Repositories may also employ the Identify verb to return additional - * descriptive information. - * @return identify request - */ - IdentifyRequest newIdentifyRequest(); - - IdentifyRequest resume(IdentifyRequest request, ResumptionToken token); - - /** - * This verb is an abbreviated form of ListRecords, retrieving only - * headers rather than records. Optional arguments permit selective - * harvesting of headers based on set membership and/or datestamp. - * Depending on the repository's support for deletions, a returned - * header may have a status attribute of "deleted" if a record - * matching the arguments specified in the request has been deleted. - * @return list identifiers request - * - */ - ListIdentifiersRequest newListIdentifiersRequest(); - - ListIdentifiersRequest resume(ListIdentifiersRequest request, ResumptionToken token); - - /** - * This verb is used to retrieve the metadata formats available - * from a repository. An optional argument restricts the request - * to the formats available for a specific item. - * @return list metadata formats request - */ - ListMetadataFormatsRequest newListMetadataFormatsRequest(); - - ListMetadataFormatsRequest resume(ListMetadataFormatsRequest request, ResumptionToken token); - - /** - * This verb is used to retrieve the set structure of a repository, - * useful for selective harvesting. - * @return list sets request - */ - ListSetsRequest newListSetsRequest(); - - ListSetsRequest resume(ListSetsRequest request, ResumptionToken token); - - /** - * This verb is used to harvest records from a repository. - * Optional arguments permit selective harvesting of records based on - * set membership and/or datestamp. Depending on the repository's - * support for deletions, a returned header may have a status - * attribute of "deleted" if a record matching the arguments - * specified in the request has been deleted. No metadata - * will be present for records with deleted status. - * @return list records request - */ - ListRecordsRequest newListRecordsRequest(); - - ListRecordsRequest resume(ListRecordsRequest request, ResumptionToken token); - - /** - * This verb is used to retrieve an individual metadata record from - * a repository. Required arguments specify the identifier of the item - * from which the record is requested and the format of the metadata - * that should be included in the record. Depending on the level at - * which a repository tracks deletions, a header with a "deleted" value - * for the status attribute may be returned, in case the metadata format - * specified by the metadataPrefix is no longer available from the - * repository or from the specified item. - * @return get record request - */ - GetRecordRequest newGetRecordRequest(); - - GetRecordRequest resume(GetRecordRequest request, ResumptionToken token); - -} diff --git a/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordRequest.java b/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordRequest.java index a196b85..ad12ab1 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordRequest.java +++ b/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordRequest.java @@ -1,11 +1,11 @@ package org.xbib.oai.client.getrecord; -import org.xbib.oai.client.ClientOAIRequest; +import org.xbib.oai.client.AbstractOAIRequest; /** * */ -public class GetRecordRequest extends ClientOAIRequest { +public class GetRecordRequest extends AbstractOAIRequest { public GetRecordRequest() { super(); diff --git a/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordResponse.java b/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordResponse.java index 80844c1..ec577e7 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordResponse.java +++ b/oai-client/src/main/java/org/xbib/oai/client/getrecord/GetRecordResponse.java @@ -1,18 +1,17 @@ package org.xbib.oai.client.getrecord; import org.xbib.helianthus.common.http.AggregatedHttpMessage; -import org.xbib.oai.client.ClientOAIResponse; +import org.xbib.oai.client.AbstractOAIResponse; -import java.io.IOException; import java.io.Writer; /** * */ -public class GetRecordResponse implements ClientOAIResponse { +public class GetRecordResponse extends AbstractOAIResponse { @Override - public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException { + public void receivedResponse(AggregatedHttpMessage message, Writer writer) { // not implemented yet } } diff --git a/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyRequest.java b/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyRequest.java index 158bc19..61934cb 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyRequest.java +++ b/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyRequest.java @@ -1,12 +1,11 @@ package org.xbib.oai.client.identify; -import org.xbib.oai.OAIRequest; -import org.xbib.oai.client.ClientOAIRequest; +import org.xbib.oai.client.AbstractOAIRequest; /** * */ -public class IdentifyRequest extends ClientOAIRequest implements OAIRequest { +public class IdentifyRequest extends AbstractOAIRequest { public IdentifyRequest() { super(); diff --git a/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyResponse.java b/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyResponse.java index 4c19673..6beba49 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyResponse.java +++ b/oai-client/src/main/java/org/xbib/oai/client/identify/IdentifyResponse.java @@ -4,7 +4,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xbib.helianthus.common.http.AggregatedHttpMessage; -import org.xbib.oai.client.ClientOAIResponse; +import org.xbib.oai.client.AbstractOAIResponse; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -22,7 +22,7 @@ import javax.xml.parsers.ParserConfigurationException; /** * */ -public class IdentifyResponse implements ClientOAIResponse { +public class IdentifyResponse extends AbstractOAIResponse { private String repositoryName; diff --git a/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersRequest.java b/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersRequest.java index 340ee9b..405ebc4 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersRequest.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersRequest.java @@ -1,12 +1,11 @@ package org.xbib.oai.client.listidentifiers; -import org.xbib.oai.OAIRequest; -import org.xbib.oai.client.ClientOAIRequest; +import org.xbib.oai.client.AbstractOAIRequest; /** * */ -public class ListIdentifiersRequest extends ClientOAIRequest implements OAIRequest { +public class ListIdentifiersRequest extends AbstractOAIRequest { public ListIdentifiersRequest() { super(); diff --git a/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersResponse.java b/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersResponse.java index 2a132a4..cb211ae 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersResponse.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listidentifiers/ListIdentifiersResponse.java @@ -1,7 +1,7 @@ package org.xbib.oai.client.listidentifiers; import org.xbib.helianthus.common.http.AggregatedHttpMessage; -import org.xbib.oai.client.ClientOAIResponse; +import org.xbib.oai.client.AbstractOAIResponse; import java.io.IOException; import java.io.Writer; @@ -9,7 +9,7 @@ import java.io.Writer; /** * */ -public class ListIdentifiersResponse implements ClientOAIResponse { +public class ListIdentifiersResponse extends AbstractOAIResponse { @Override public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException { diff --git a/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsRequest.java b/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsRequest.java index d0c70f8..aa27825 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsRequest.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsRequest.java @@ -1,16 +1,14 @@ package org.xbib.oai.client.listmetadataformats; -import org.xbib.oai.OAIRequest; -import org.xbib.oai.client.ClientOAIRequest; +import org.xbib.oai.client.AbstractOAIRequest; /** * */ -public class ListMetadataFormatsRequest extends ClientOAIRequest implements OAIRequest { +public class ListMetadataFormatsRequest extends AbstractOAIRequest { public ListMetadataFormatsRequest() { super(); addParameter(VERB_PARAMETER, LIST_METADATA_FORMATS); } - } diff --git a/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsResponse.java b/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsResponse.java index 3ce504d..5a8f478 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsResponse.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listmetadataformats/ListMetadataFormatsResponse.java @@ -1,7 +1,7 @@ package org.xbib.oai.client.listmetadataformats; import org.xbib.helianthus.common.http.AggregatedHttpMessage; -import org.xbib.oai.client.ClientOAIResponse; +import org.xbib.oai.client.AbstractOAIResponse; import java.io.IOException; import java.io.Writer; @@ -9,7 +9,7 @@ import java.io.Writer; /** * */ -public class ListMetadataFormatsResponse implements ClientOAIResponse { +public class ListMetadataFormatsResponse extends AbstractOAIResponse { @Override public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException { diff --git a/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsRequest.java b/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsRequest.java index 497d19c..f5955c2 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsRequest.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsRequest.java @@ -1,7 +1,7 @@ package org.xbib.oai.client.listrecords; import org.xbib.oai.OAIConstants; -import org.xbib.oai.client.ClientOAIRequest; +import org.xbib.oai.client.AbstractOAIRequest; import org.xbib.oai.xml.MetadataHandler; import java.util.LinkedList; @@ -10,7 +10,7 @@ import java.util.List; /** * */ -public class ListRecordsRequest extends ClientOAIRequest { +public class ListRecordsRequest extends AbstractOAIRequest { private List handlers = new LinkedList<>(); diff --git a/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsResponse.java b/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsResponse.java index 3274517..86d2d67 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsResponse.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listrecords/ListRecordsResponse.java @@ -5,7 +5,7 @@ import io.netty.util.AsciiString; import org.xbib.content.xml.transform.TransformerURIResolver; import org.xbib.content.xml.util.XMLUtil; import org.xbib.helianthus.common.http.AggregatedHttpMessage; -import org.xbib.oai.client.ClientOAIResponse; +import org.xbib.oai.client.AbstractOAIResponse; import org.xbib.oai.exceptions.BadArgumentException; import org.xbib.oai.exceptions.BadResumptionTokenException; import org.xbib.oai.exceptions.NoRecordsMatchException; @@ -32,7 +32,7 @@ import javax.xml.transform.stream.StreamResult; /** * */ -public class ListRecordsResponse implements ClientOAIResponse { +public class ListRecordsResponse extends AbstractOAIResponse { private static final Logger logger = Logger.getLogger(ListRecordsResponse.class.getName()); private static final String[] RETRY_AFTER_HEADERS = { diff --git a/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsRequest.java b/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsRequest.java index e1f44fa..f32dcf5 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsRequest.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsRequest.java @@ -1,11 +1,11 @@ package org.xbib.oai.client.listsets; -import org.xbib.oai.client.ClientOAIRequest; +import org.xbib.oai.client.AbstractOAIRequest; /** * */ -public class ListSetsRequest extends ClientOAIRequest { +public class ListSetsRequest extends AbstractOAIRequest { public ListSetsRequest() { super(); diff --git a/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsResponse.java b/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsResponse.java index 1a8d0ee..0103439 100644 --- a/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsResponse.java +++ b/oai-client/src/main/java/org/xbib/oai/client/listsets/ListSetsResponse.java @@ -1,7 +1,7 @@ package org.xbib.oai.client.listsets; import org.xbib.helianthus.common.http.AggregatedHttpMessage; -import org.xbib.oai.client.ClientOAIResponse; +import org.xbib.oai.client.AbstractOAIResponse; import java.io.IOException; import java.io.Writer; @@ -9,7 +9,7 @@ import java.io.Writer; /** * */ -public class ListSetsResponse implements ClientOAIResponse { +public class ListSetsResponse extends AbstractOAIResponse { @Override public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException { diff --git a/oai-client/src/test/java/org/xbib/oai/client/ArxivClientTest.java b/oai-client/src/test/java/org/xbib/oai/client/ArxivClientTest.java index f42aec4..b067fb4 100644 --- a/oai-client/src/test/java/org/xbib/oai/client/ArxivClientTest.java +++ b/oai-client/src/test/java/org/xbib/oai/client/ArxivClientTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertTrue; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.Ignore; import org.junit.Test; import org.xbib.helianthus.client.http.HttpClient; import org.xbib.helianthus.common.http.AggregatedHttpMessage; @@ -15,8 +16,6 @@ import org.xbib.oai.client.identify.IdentifyResponse; import org.xbib.oai.client.listrecords.ListRecordsRequest; import org.xbib.oai.client.listrecords.ListRecordsResponse; import org.xbib.oai.xml.SimpleMetadataHandler; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; import java.io.File; import java.io.FileWriter; @@ -33,13 +32,14 @@ import java.util.concurrent.atomic.AtomicLong; /** * */ +@Ignore public class ArxivClientTest { private static final Logger logger = LogManager.getLogger(ArxivClientTest.class.getName()); @Test public void testListRecordsArxiv() throws Exception { - try (DefaultOAIClient client = new DefaultOAIClient().setURL(new URL("http://export.arxiv.org/oai2"))) { + try (OAIClient client = new OAIClient().setURL(new URL("http://export.arxiv.org/oai2"))) { IdentifyRequest identifyRequest = client.newIdentifyRequest(); HttpClient httpClient = client.getHttpClient(); AggregatedHttpMessage response = httpClient.execute(HttpHeaders.of(HttpMethod.GET, identifyRequest.getPath()) @@ -58,46 +58,13 @@ public class ArxivClientTest { listRecordsRequest.setFrom(Instant.parse("2016-11-01T00:00:00Z")); listRecordsRequest.setUntil(Instant.parse("2016-11-02T00:00:00Z")); listRecordsRequest.setMetadataPrefix("arXiv"); - final AtomicLong count = new AtomicLong(0L); - SimpleMetadataHandler simpleMetadataHandler = new SimpleMetadataHandler() { - @Override - public void startDocument() throws SAXException { - logger.debug("start doc"); - } - - @Override - public void endDocument() throws SAXException { - logger.debug("end doc"); - count.incrementAndGet(); - } - - @Override - public void startPrefixMapping(String prefix, String uri) throws SAXException { - } - - @Override - public void endPrefixMapping(String prefix) throws SAXException { - } - - @Override - public void startElement(String ns, String localname, String qname, Attributes atrbts) throws SAXException { - } - - @Override - public void endElement(String ns, String localname, String qname) throws SAXException { - } - - @Override - public void characters(char[] chars, int pos, int len) throws SAXException { - } - - }; + Handler handler = new Handler(); File file = File.createTempFile("arxiv.", ".xml"); file.deleteOnExit(); FileWriter fileWriter = new FileWriter(file); while (listRecordsRequest != null) { try { - listRecordsRequest.addHandler(simpleMetadataHandler); + listRecordsRequest.addHandler(handler); ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest); logger.info("sending {}", listRecordsRequest.getPath()); response = httpClient.execute(HttpHeaders.of(HttpMethod.GET, listRecordsRequest.getPath()) @@ -112,12 +79,32 @@ public class ArxivClientTest { } } fileWriter.close(); - logger.info("count={}", count.get()); - assertTrue(count.get() > 0L); + logger.info("count={}", handler.count()); + assertTrue(handler.count() > 0L); } catch (ConnectException | ExecutionException e) { logger.warn("skipped, can not connect", e); } catch (InterruptedException | IOException e) { throw e; } } + + class Handler extends SimpleMetadataHandler { + + final AtomicLong count = new AtomicLong(0L); + + @Override + public void startDocument() { + logger.debug("start doc"); + } + + @Override + public void endDocument() { + logger.debug("end doc"); + count.incrementAndGet(); + } + + long count() { + return count.get(); + } + } } diff --git a/oai-client/src/test/java/org/xbib/oai/client/BundeskunsthalleTest.java b/oai-client/src/test/java/org/xbib/oai/client/BundeskunsthalleTest.java new file mode 100644 index 0000000..f127cc9 --- /dev/null +++ b/oai-client/src/test/java/org/xbib/oai/client/BundeskunsthalleTest.java @@ -0,0 +1,112 @@ +package org.xbib.oai.client; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.Test; +import org.xbib.helianthus.client.Clients; +import org.xbib.helianthus.client.http.HttpClient; +import org.xbib.helianthus.common.http.AggregatedHttpMessage; +import org.xbib.helianthus.common.http.HttpHeaderNames; +import org.xbib.helianthus.common.http.HttpHeaders; +import org.xbib.helianthus.common.http.HttpMethod; +import org.xbib.marc.Marc; +import org.xbib.marc.json.MarcJsonWriter; +import org.xbib.marc.xml.MarcContentHandler; +import org.xbib.oai.client.identify.IdentifyRequest; +import org.xbib.oai.client.identify.IdentifyResponse; +import org.xbib.oai.client.listrecords.ListRecordsRequest; +import org.xbib.oai.client.listrecords.ListRecordsResponse; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.net.ConnectException; +import java.net.URI; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.ExecutionException; + +/** + * + */ +public class BundeskunsthalleTest { + + private static final Logger logger = LogManager.getLogger(BundeskunsthalleTest.class.getName()); + + @Test + public void testListRecords() throws Exception { + String spec = "http://www.bundeskunsthalle.de/cgi-bin/bib/oai-pmh"; + try (OAIClient oaiClient = new OAIClient().setURL(new URL(spec), true)) { + IdentifyRequest identifyRequest = oaiClient.newIdentifyRequest(); + HttpClient client = oaiClient.getHttpClient(); + AggregatedHttpMessage response = client.execute(HttpHeaders.of(HttpMethod.GET, identifyRequest.getPath()) + .set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get(); + // follow a maximum of 10 HTTP redirects + int max = 10; + while (response.followUrl() != null && max-- > 0) { + URI uri = URI.create(response.followUrl()); + client = Clients.newClient(oaiClient.getFactory(), "none+" + uri, HttpClient.class); + response = client.execute(HttpHeaders.of(HttpMethod.GET, response.followUrl()) + .set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get(); + } + IdentifyResponse identifyResponse = new IdentifyResponse(); + logger.debug("identifyResponse = {}", response.content().toStringUtf8()); + identifyResponse.receivedResponse(response, new StringWriter()); + String granularity = identifyResponse.getGranularity(); + logger.info("granularity = {}", granularity); + DateTimeFormatter dateTimeFormatter = "YYYY-MM-DD".equals(granularity) ? + DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("GMT")) : null; + ListRecordsRequest listRecordsRequest = oaiClient.newListRecordsRequest(); + listRecordsRequest.setDateTimeFormatter(dateTimeFormatter); + listRecordsRequest.setMetadataPrefix("marcxml"); + try (MarcJsonWriter writer = new MarcJsonWriter("bk-bulk%d.jsonl", 1000, + MarcJsonWriter.Style.ELASTICSEARCH_BULK, 65536, false) + .setIndex("testindex", "testtype")) { + writer.startDocument(); + writer.beginCollection(); + while (listRecordsRequest != null) { + try { + ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest); + logger.debug("response = {}", response.headers()); + client = oaiClient.getHttpClient(); + response = client.execute(HttpHeaders.of(HttpMethod.GET, listRecordsRequest.getPath()) + .set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get(); + // follow a maximum of 10 HTTP redirects + max = 10; + while (response.followUrl() != null && max-- > 0) { + URI uri = URI.create(response.followUrl()); + client = Clients.newClient(oaiClient.getFactory(), "none+" + uri, HttpClient.class); + response = client.execute(HttpHeaders.of(HttpMethod.GET, response.followUrl()) + .set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get(); + } + InputStream inputStream = new ByteArrayInputStream(response.content().array()); + Marc.builder() + .setInputStream(inputStream) + .setCharset(StandardCharsets.UTF_8) + .setContentHandler(new MarcContentHandler() + .setFormat("MarcXML") + .setType("Bibliographic") + .addNamespace("http://www.loc.gov/MARC21/slim") + .setMarcListener(writer)) + .build() + .xmlReader().parse(); + listRecordsResponse.receivedResponse(response, new StringWriter()); + listRecordsRequest = oaiClient.resume(listRecordsRequest, listRecordsResponse.getResumptionToken()); + } catch (IOException e) { + logger.error(e.getMessage(), e); + listRecordsRequest = null; + } + } + writer.endCollection(); + writer.endDocument(); + } + } catch (ConnectException | ExecutionException e) { + logger.warn("skipped, can not connect, exception is:", e); + } catch (InterruptedException | IOException e) { + throw e; + } + } +} diff --git a/oai-client/src/test/java/org/xbib/oai/client/DNBClientTest.java b/oai-client/src/test/java/org/xbib/oai/client/DNBClientTest.java index 870dc0d..b2a868d 100644 --- a/oai-client/src/test/java/org/xbib/oai/client/DNBClientTest.java +++ b/oai-client/src/test/java/org/xbib/oai/client/DNBClientTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.Ignore; import org.junit.Test; import org.xbib.helianthus.client.http.HttpClient; import org.xbib.helianthus.common.http.AggregatedHttpMessage; @@ -14,8 +15,6 @@ import org.xbib.oai.client.identify.IdentifyRequest; import org.xbib.oai.client.listrecords.ListRecordsRequest; import org.xbib.oai.client.listrecords.ListRecordsResponse; import org.xbib.oai.xml.SimpleMetadataHandler; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; import java.io.File; import java.io.FileWriter; @@ -29,13 +28,14 @@ import java.util.concurrent.atomic.AtomicLong; /** * */ +@Ignore public class DNBClientTest { private static final Logger logger = LogManager.getLogger(DNBClientTest.class.getName()); @Test public void testIdentify() throws Exception { - DefaultOAIClient client = new DefaultOAIClient().setURL(new URL("http://services.dnb.de/oai/repository")); + OAIClient client = new OAIClient().setURL(new URL("http://services.dnb.de/oai/repository")); IdentifyRequest request = client.newIdentifyRequest(); HttpClient httpClient = client.getHttpClient(); assertEquals("/oai/repository?verb=Identify", request.getPath()); @@ -45,55 +45,23 @@ public class DNBClientTest { @Test public void testListRecordsDNB() throws Exception { - try (DefaultOAIClient client = new DefaultOAIClient().setURL(new URL("http://services.dnb.de/oai/repository"))){ + try (OAIClient client = new OAIClient().setURL(new URL("http://services.dnb.de/oai/repository"))){ ListRecordsRequest listRecordsRequest = client.newListRecordsRequest(); listRecordsRequest.setFrom(Instant.parse("2016-01-01T00:00:00Z")); listRecordsRequest.setUntil(Instant.parse("2016-01-10T00:00:00Z")); listRecordsRequest.setSet("bib"); listRecordsRequest.setMetadataPrefix("PicaPlus-xml"); - final AtomicLong count = new AtomicLong(0L); - SimpleMetadataHandler simpleMetadataHandler = new SimpleMetadataHandler() { - @Override - public void startDocument() throws SAXException { - logger.debug("startDocument"); - } - - @Override - public void endDocument() throws SAXException { - count.incrementAndGet(); - logger.debug("endDocument"); - } - - @Override - public void startPrefixMapping(String prefix, String uri) throws SAXException { - } - - @Override - public void endPrefixMapping(String prefix) throws SAXException { - } - - @Override - public void startElement(String ns, String localname, String qname, Attributes atrbts) throws SAXException { - } - - @Override - public void endElement(String ns, String localname, String qname) throws SAXException { - } - - @Override - public void characters(char[] chars, int pos, int len) throws SAXException { - } - - }; + Handler handler = new Handler(); File file = File.createTempFile("dnb-bib-pica.", ".xml"); file.deleteOnExit(); FileWriter sw = new FileWriter(file); while (listRecordsRequest != null) { try { ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest); - listRecordsRequest.addHandler(simpleMetadataHandler); + listRecordsRequest.addHandler(handler); HttpClient httpClient = client.getHttpClient(); - AggregatedHttpMessage response = httpClient.execute(HttpHeaders.of(HttpMethod.GET, listRecordsRequest.getPath()) + AggregatedHttpMessage response = + httpClient.execute(HttpHeaders.of(HttpMethod.GET, listRecordsRequest.getPath()) .set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get(); String content = response.content().toStringUtf8(); listRecordsResponse.receivedResponse(response, sw); @@ -104,11 +72,31 @@ public class DNBClientTest { } } sw.close(); - logger.info("count={}", count.get()); + logger.info("count={}", handler.count()); } catch (ConnectException | ExecutionException e) { logger.warn("skipped, can not connect"); } catch (IOException e) { logger.warn("skipped, HTTP exception"); } } + + class Handler extends SimpleMetadataHandler { + + final AtomicLong count = new AtomicLong(0L); + + @Override + public void startDocument() { + logger.debug("start doc"); + } + + @Override + public void endDocument() { + logger.debug("end doc"); + count.incrementAndGet(); + } + + long count() { + return count.get(); + } + } } diff --git a/oai-client/src/test/java/org/xbib/oai/client/DOAJClientTest.java b/oai-client/src/test/java/org/xbib/oai/client/DOAJClientTest.java index bd86ca3..311b376 100644 --- a/oai-client/src/test/java/org/xbib/oai/client/DOAJClientTest.java +++ b/oai-client/src/test/java/org/xbib/oai/client/DOAJClientTest.java @@ -2,6 +2,7 @@ package org.xbib.oai.client; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.Ignore; import org.junit.Test; import org.xbib.helianthus.client.Clients; import org.xbib.helianthus.client.http.HttpClient; @@ -14,8 +15,6 @@ import org.xbib.oai.client.identify.IdentifyResponse; import org.xbib.oai.client.listrecords.ListRecordsRequest; import org.xbib.oai.client.listrecords.ListRecordsResponse; import org.xbib.oai.xml.SimpleMetadataHandler; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; import java.io.File; import java.io.FileWriter; @@ -30,11 +29,10 @@ import java.time.format.DateTimeFormatter; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicLong; -import static org.junit.Assert.assertTrue; - /** * */ +@Ignore public class DOAJClientTest { private static final Logger logger = LogManager.getLogger(DOAJClientTest.class.getName()); @@ -42,7 +40,7 @@ public class DOAJClientTest { @Test public void testListRecordsDOAJ() throws Exception { // will redirect to https://doaj.org/oai - try (DefaultOAIClient oaiClient = new DefaultOAIClient().setURL(new URL("http://doaj.org/oai"), true)) { + try (OAIClient oaiClient = new OAIClient().setURL(new URL("http://doaj.org/oai"), true)) { IdentifyRequest identifyRequest = oaiClient.newIdentifyRequest(); HttpClient client = oaiClient.getHttpClient(); AggregatedHttpMessage response = client.execute(HttpHeaders.of(HttpMethod.GET, identifyRequest.getPath()) @@ -65,48 +63,18 @@ public class DOAJClientTest { DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("GMT")) : null; ListRecordsRequest listRecordsRequest = oaiClient.newListRecordsRequest(); listRecordsRequest.setDateTimeFormatter(dateTimeFormatter); - listRecordsRequest.setFrom(Instant.parse("2016-01-06T00:00:00Z")); - listRecordsRequest.setUntil(Instant.parse("2016-11-07T00:00:00Z")); + listRecordsRequest.setFrom(Instant.parse("2017-01-01T00:00:00Z")); + listRecordsRequest.setUntil(Instant.parse("2018-01-01T00:00:00Z")); listRecordsRequest.setMetadataPrefix("oai_dc"); - final AtomicLong count = new AtomicLong(0L); - SimpleMetadataHandler simpleMetadataHandler = new SimpleMetadataHandler() { - @Override - public void startDocument() throws SAXException { - logger.debug("start doc"); - } - - @Override - public void endDocument() throws SAXException { - logger.debug("end doc"); - count.incrementAndGet(); - } - - @Override - public void startPrefixMapping(String prefix, String uri) throws SAXException { - } - - @Override - public void endPrefixMapping(String prefix) throws SAXException { - } - - @Override - public void startElement(String ns, String localname, String qname, Attributes atrbts) throws SAXException { - } - - @Override - public void endElement(String ns, String localname, String qname) throws SAXException { - } - - @Override - public void characters(char[] chars, int pos, int len) throws SAXException { - } - }; - File file = File.createTempFile("doaj.", ".xml"); + Handler handler = new Handler(); + File file = File.createTempFile("doaj.", ".xml"); file.deleteOnExit(); FileWriter fileWriter = new FileWriter(file); while (listRecordsRequest != null) { try { - listRecordsRequest.addHandler(simpleMetadataHandler); + ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest); + logger.debug("response = {}", response.headers()); + listRecordsRequest.addHandler(handler); client = oaiClient.getHttpClient(); response = client.execute(HttpHeaders.of(HttpMethod.GET, listRecordsRequest.getPath()) .set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get(); @@ -118,8 +86,6 @@ public class DOAJClientTest { response = client.execute(HttpHeaders.of(HttpMethod.GET, response.followUrl()) .set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get(); } - ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest); - logger.debug("response = {}", response.headers()); listRecordsResponse.receivedResponse(response, fileWriter); listRecordsRequest = oaiClient.resume(listRecordsRequest, listRecordsResponse.getResumptionToken()); } catch (IOException e) { @@ -128,8 +94,7 @@ public class DOAJClientTest { } } fileWriter.close(); - logger.info("count={}", count.get()); - assertTrue(count.get() > 0L); + logger.info("count={}", handler.count()); } catch (ConnectException | ExecutionException e) { logger.warn("skipped, can not connect, exception is:", e); } catch (InterruptedException | IOException e) { @@ -137,4 +102,23 @@ public class DOAJClientTest { } } + class Handler extends SimpleMetadataHandler { + + final AtomicLong count = new AtomicLong(0L); + + @Override + public void startDocument() { + logger.debug("start doc"); + } + + @Override + public void endDocument() { + logger.debug("end doc"); + count.incrementAndGet(); + } + + long count() { + return count.get(); + } + } } diff --git a/oai-common/build.gradle b/oai-common/build.gradle index d254a22..e0d37a4 100644 --- a/oai-common/build.gradle +++ b/oai-common/build.gradle @@ -1,3 +1,3 @@ dependencies { - compile "org.xbib:content-rdf:1.0.5" + compile "org.xbib:content-rdf:${project.property('xbib-content.version')}" } diff --git a/oai-server/src/main/java/org/xbib/oai/server/ServerOAIRequest.java b/oai-server/src/main/java/org/xbib/oai/server/AbstractOAIRequest.java similarity index 95% rename from oai-server/src/main/java/org/xbib/oai/server/ServerOAIRequest.java rename to oai-server/src/main/java/org/xbib/oai/server/AbstractOAIRequest.java index 84a1228..d6d7a31 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/ServerOAIRequest.java +++ b/oai-server/src/main/java/org/xbib/oai/server/AbstractOAIRequest.java @@ -11,7 +11,7 @@ import java.util.Map; /** * */ -public abstract class ServerOAIRequest implements OAIRequest { +public abstract class AbstractOAIRequest implements OAIRequest { private String path; @@ -29,7 +29,7 @@ public abstract class ServerOAIRequest implements OAIRequest { private boolean retry; - protected ServerOAIRequest() { + protected AbstractOAIRequest() { this.parameters = new HashMap<>(); } diff --git a/oai-server/src/main/java/org/xbib/oai/server/ServerOAIResponse.java b/oai-server/src/main/java/org/xbib/oai/server/AbstractOAIResponse.java similarity index 70% rename from oai-server/src/main/java/org/xbib/oai/server/ServerOAIResponse.java rename to oai-server/src/main/java/org/xbib/oai/server/AbstractOAIResponse.java index 31b9e88..bcea4d2 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/ServerOAIResponse.java +++ b/oai-server/src/main/java/org/xbib/oai/server/AbstractOAIResponse.java @@ -7,11 +7,11 @@ import javax.xml.stream.util.XMLEventConsumer; /** * Default OAI response. */ -public class ServerOAIResponse implements OAIResponse { +public abstract class AbstractOAIResponse implements OAIResponse { private XMLEventConsumer consumer; - public ServerOAIResponse setConsumer(XMLEventConsumer consumer) { + public AbstractOAIResponse setConsumer(XMLEventConsumer consumer) { this.consumer = consumer; return this; } diff --git a/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerRequest.java b/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerRequest.java index 3c06305..a3e9fcf 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerRequest.java +++ b/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerRequest.java @@ -1,10 +1,10 @@ package org.xbib.oai.server.getrecord; -import org.xbib.oai.server.ServerOAIRequest; +import org.xbib.oai.server.AbstractOAIRequest; /** * */ -public class GetRecordServerRequest extends ServerOAIRequest { +public class GetRecordServerRequest extends AbstractOAIRequest { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerResponse.java b/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerResponse.java index a22105e..bb8ee5a 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerResponse.java +++ b/oai-server/src/main/java/org/xbib/oai/server/getrecord/GetRecordServerResponse.java @@ -1,9 +1,9 @@ package org.xbib.oai.server.getrecord; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIResponse; /** * */ -public class GetRecordServerResponse extends ServerOAIResponse { +public class GetRecordServerResponse extends AbstractOAIResponse { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerRequest.java b/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerRequest.java index 918b259..5f1e386 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerRequest.java +++ b/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerRequest.java @@ -1,9 +1,9 @@ package org.xbib.oai.server.identify; -import org.xbib.oai.server.ServerOAIRequest; +import org.xbib.oai.server.AbstractOAIRequest; /** * */ -public class IdentifyServerRequest extends ServerOAIRequest { +public class IdentifyServerRequest extends AbstractOAIRequest { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerResponse.java b/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerResponse.java index 1dc4927..8e0904d 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerResponse.java +++ b/oai-server/src/main/java/org/xbib/oai/server/identify/IdentifyServerResponse.java @@ -1,6 +1,6 @@ package org.xbib.oai.server.identify; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIResponse; import java.net.URL; import java.util.ArrayList; @@ -10,7 +10,7 @@ import java.util.List; /** * */ -public class IdentifyServerResponse extends ServerOAIResponse { +public class IdentifyServerResponse extends AbstractOAIResponse { private String repositoryName; diff --git a/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerRequest.java b/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerRequest.java index d338bf8..d45637c 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerRequest.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerRequest.java @@ -1,10 +1,10 @@ package org.xbib.oai.server.listidentifiers; -import org.xbib.oai.server.ServerOAIRequest; +import org.xbib.oai.server.AbstractOAIRequest; /** * */ -public class ListIdentifiersServerRequest extends ServerOAIRequest { +public class ListIdentifiersServerRequest extends AbstractOAIRequest { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerResponse.java b/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerResponse.java index 037bc6e..9af1f7f 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerResponse.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listidentifiers/ListIdentifiersServerResponse.java @@ -1,10 +1,10 @@ package org.xbib.oai.server.listidentifiers; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIResponse; /** * */ -public class ListIdentifiersServerResponse extends ServerOAIResponse { +public class ListIdentifiersServerResponse extends AbstractOAIResponse { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerRequest.java b/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerRequest.java index b6db919..fc5ef51 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerRequest.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerRequest.java @@ -1,10 +1,10 @@ package org.xbib.oai.server.listmetadataformats; -import org.xbib.oai.server.ServerOAIRequest; +import org.xbib.oai.server.AbstractOAIRequest; /** * */ -public class ListMetadataFormatsServerRequest extends ServerOAIRequest { +public class ListMetadataFormatsServerRequest extends AbstractOAIRequest { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerResponse.java b/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerResponse.java index 50ed930..e6d26bb 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerResponse.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listmetadataformats/ListMetadataFormatsServerResponse.java @@ -1,10 +1,10 @@ package org.xbib.oai.server.listmetadataformats; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIResponse; /** * */ -public class ListMetadataFormatsServerResponse extends ServerOAIResponse { +public class ListMetadataFormatsServerResponse extends AbstractOAIResponse { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerRequest.java b/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerRequest.java index 5b1248f..fc16e56 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerRequest.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerRequest.java @@ -1,10 +1,10 @@ package org.xbib.oai.server.listrecords; -import org.xbib.oai.server.ServerOAIRequest; +import org.xbib.oai.server.AbstractOAIRequest; /** * */ -public class ListRecordsServerRequest extends ServerOAIRequest { +public class ListRecordsServerRequest extends AbstractOAIRequest { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerResponse.java b/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerResponse.java index c002c4f..8cdda87 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerResponse.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listrecords/ListRecordsServerResponse.java @@ -1,13 +1,13 @@ package org.xbib.oai.server.listrecords; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIResponse; import java.util.Date; /** * */ -public class ListRecordsServerResponse extends ServerOAIResponse { +public class ListRecordsServerResponse extends AbstractOAIResponse { private String error; diff --git a/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerRequest.java b/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerRequest.java index 6e99d10..8e59dd8 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerRequest.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerRequest.java @@ -1,10 +1,10 @@ package org.xbib.oai.server.listsets; -import org.xbib.oai.server.ServerOAIRequest; +import org.xbib.oai.server.AbstractOAIRequest; /** * */ -public class ListSetsServerRequest extends ServerOAIRequest { +public class ListSetsServerRequest extends AbstractOAIRequest { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerResponse.java b/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerResponse.java index c85aff8..4b62228 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerResponse.java +++ b/oai-server/src/main/java/org/xbib/oai/server/listsets/ListSetsServerResponse.java @@ -1,9 +1,9 @@ package org.xbib.oai.server.listsets; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIResponse; /** * */ -public class ListSetsServerResponse extends ServerOAIResponse { +public class ListSetsServerResponse extends AbstractOAIResponse { } diff --git a/oai-server/src/main/java/org/xbib/oai/server/verb/AbstractVerb.java b/oai-server/src/main/java/org/xbib/oai/server/verb/AbstractVerb.java index 3460eb2..bb27c90 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/verb/AbstractVerb.java +++ b/oai-server/src/main/java/org/xbib/oai/server/verb/AbstractVerb.java @@ -3,10 +3,9 @@ package org.xbib.oai.server.verb; import org.xbib.oai.OAIConstants; import org.xbib.oai.exceptions.OAIException; import org.xbib.oai.server.OAIServer; -import org.xbib.oai.server.ServerOAIRequest; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIRequest; +import org.xbib.oai.server.AbstractOAIResponse; -import java.io.IOException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; @@ -29,22 +28,22 @@ public abstract class AbstractVerb { private static final String NS_PREFIX = "xsi"; - private final ServerOAIRequest request; + private final AbstractOAIRequest request; - private final ServerOAIResponse response; + private final AbstractOAIResponse response; - public AbstractVerb(ServerOAIRequest request, ServerOAIResponse response) { + public AbstractVerb(AbstractOAIRequest request, AbstractOAIResponse response) { this.request = request; this.response = response; } - public abstract void execute(OAIServer adapter) throws OAIException; + public abstract void execute(OAIServer server) throws OAIException; protected void beginDocument() throws XMLStreamException { response.getConsumer().add(eventFactory.createStartDocument()); } - protected void endDocument() throws XMLStreamException, IOException { + protected void endDocument() throws XMLStreamException { response.getConsumer().add(eventFactory.createEndDocument()); } diff --git a/oai-server/src/main/java/org/xbib/oai/server/verb/Identify.java b/oai-server/src/main/java/org/xbib/oai/server/verb/Identify.java index e837f81..6c7b40a 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/verb/Identify.java +++ b/oai-server/src/main/java/org/xbib/oai/server/verb/Identify.java @@ -15,10 +15,10 @@ public class Identify extends AbstractVerb { } @Override - public void execute(OAIServer adapter) throws OAIException { + public void execute(OAIServer server) throws OAIException { try { beginDocument(); - beginOAIPMH(adapter.getBaseURL()); + beginOAIPMH(server.getBaseURL()); beginElement("Identify"); endElement("Identify"); endOAIPMH(); diff --git a/oai-server/src/main/java/org/xbib/oai/server/verb/ListMetadataFormats.java b/oai-server/src/main/java/org/xbib/oai/server/verb/ListMetadataFormats.java index 75a30f8..72d3cad 100644 --- a/oai-server/src/main/java/org/xbib/oai/server/verb/ListMetadataFormats.java +++ b/oai-server/src/main/java/org/xbib/oai/server/verb/ListMetadataFormats.java @@ -2,15 +2,15 @@ package org.xbib.oai.server.verb; import org.xbib.oai.exceptions.OAIException; import org.xbib.oai.server.OAIServer; -import org.xbib.oai.server.ServerOAIRequest; -import org.xbib.oai.server.ServerOAIResponse; +import org.xbib.oai.server.AbstractOAIRequest; +import org.xbib.oai.server.AbstractOAIResponse; /** * */ public class ListMetadataFormats extends AbstractVerb { - public ListMetadataFormats(ServerOAIRequest request, ServerOAIResponse response) { + public ListMetadataFormats(AbstractOAIRequest request, AbstractOAIResponse response) { super(request, response); } diff --git a/oai-server/src/test/java/org/xbib/oai/server/SimpleServer.java b/oai-server/src/test/java/org/xbib/oai/server/SimpleServer.java index a781e31..a5007e4 100644 --- a/oai-server/src/test/java/org/xbib/oai/server/SimpleServer.java +++ b/oai-server/src/test/java/org/xbib/oai/server/SimpleServer.java @@ -16,7 +16,6 @@ import org.xbib.oai.server.listsets.ListSetsServerResponse; import org.xbib.oai.server.verb.Identify; import java.net.MalformedURLException; -import java.net.URISyntaxException; import java.net.URL; import java.util.Date; diff --git a/settings.gradle b/settings.gradle index 75b407e..4121f54 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,5 @@ -rootProject.name = 'oai' +rootProject.name = name + include 'oai-common' include 'oai-client' include 'oai-server'