move to xbib netty http client

This commit is contained in:
Jörg Prante 2019-08-08 01:05:54 +02:00
parent a7c7573592
commit 234edaf99c
40 changed files with 470 additions and 1504 deletions

View file

@ -1,8 +0,0 @@
sudo: false
language: java
jdk:
- oraclejdk8
cache:
directories:
- $HOME/.m2

View file

@ -1,33 +1,19 @@
plugins {
id "com.github.spotbugs" version "2.0.0"
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"
id "org.xbib.gradle.plugin.asciidoctor" version "1.6.0.1"
}
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
apply plugin: "io.codearte.nexus-staging"
allprojects {
subprojects {
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'findbugs'
apply plugin: 'pmd'
apply plugin: 'checkstyle'
apply plugin: "jacoco"
apply plugin: "com.github.spotbugs"
apply plugin: 'org.xbib.gradle.plugin.asciidoctor'
repositories {
@ -35,26 +21,28 @@ allprojects {
}
configurations {
alpnagent
asciidoclet
wagon
}
dependencies {
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
targetCompatibility = JavaVersion.VERSION_1_8
compileJava {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
compileTestJava {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:all" << "-profile" << "compact2"
options.compilerArgs << "-Xlint:all"
}
clean {
@ -62,11 +50,11 @@ allprojects {
}
test {
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'
testLogging {
showStandardStreams = false
showStandardStreams = true
exceptionFormat = 'full'
}
systemProperty 'java.util.logging.manager', 'org.apache.logging.log4j.jul.LogManager'
}
task sourcesJar(type: Jar, dependsOn: classes) {
@ -82,14 +70,107 @@ allprojects {
archives sourcesJar, javadocJar
}
if (project.hasProperty('signing.keyId')) {
signing {
sign configurations.archives
ext {
user = 'xbib'
projectName = 'oai'
projectDescription = 'Open Archive Initiative library for Java'
scmUrl = 'https://github.com/xbib/oai'
scmConnection = 'scm:git:git://github.com/xbib/oai.git'
scmDeveloperConnection = 'scm:git:git://github.com/xbib/oai.git'
}
task sonatypeUpload(type: Upload, dependsOn: build) {
group = 'publish'
configuration = configurations.archives
uploadDescriptor = true
repositories {
if (project.hasProperty('ossrhUsername')) {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: uri(ossrhReleaseUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
snapshotRepository(url: uri(ossrhSnapshotUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
pom.project {
groupId project.group
artifactId project.name
version project.version
name project.name
description projectDescription
packaging 'jar'
inceptionYear '2016'
url scmUrl
organization {
name 'xbib'
url 'http://xbib.org'
}
developers {
developer {
id user
name 'Jörg Prante'
email 'joergprante@gmail.com'
url 'https://github.com/jprante'
}
}
scm {
url scmUrl
connection scmConnection
developerConnection scmDeveloperConnection
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
}
}
}
}
}
apply from: "${rootProject.projectDir}/gradle/ext.gradle"
apply from: "${rootProject.projectDir}/gradle/publish.gradle"
apply from: "${rootProject.projectDir}/gradle/sonarqube.gradle"
nexusStaging {
packageGroup = "org.xbib"
}
spotbugs {
effort = "max"
reportLevel = "low"
}
tasks.withType(com.github.spotbugs.SpotBugsTask) {
ignoreFailures = true
reports {
xml.enabled = false
html.enabled = true
}
}
tasks.withType(Pmd) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
tasks.withType(Checkstyle) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
sonarqube {
properties {
property "sonar.projectName", "${project.group} ${project.name}"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", "src/test/java"
property "sonar.scm.provider", "git"
property "sonar.junit.reportsPath", "build/test-results/test/"
}
}
}

View file

@ -1,14 +1,18 @@
group = org.xbib
name = oai
version = 1.2.1
version = 1.3.0
xbib-content.version = 1.3.0
xbib-marc.version = 1.1.0
xbib-bibliographic-character-sets.version = 1.0.0
helianthus.version = 1.0.13
tcnative.version = 2.0.7.Final
alpnagent.version = 2.0.7
xbib-content.version = 1.3.1
xbib-netty-http.version = 4.1.38.2
tcnative.version = 2.0.25.Final
# test
junit.version 4.12
log4j.version = 2.10.0
wagon.version = 3.0.0
asciidoclet.version = 1.5.4
xbib-bibliographic-character-sets.version = 1.0.0
xbib-marc.version = 1.1.0
# doc
asciidoclet.version = 1.5.4
org.gradle.warning.mode = all
org.gradle.daemon = false

View file

@ -1,8 +0,0 @@
ext {
user = 'xbib'
projectName = 'oai'
projectDescription = 'Open Archive Initiative library for Java'
scmUrl = 'https://github.com/xbib/oai'
scmConnection = 'scm:git:git://github.com/xbib/oai.git'
scmDeveloperConnection = 'scm:git:git://github.com/xbib/oai.git'
}

View file

@ -1,72 +0,0 @@
task xbibUpload(type: Upload, dependsOn: build) {
group = 'publish'
configuration = configurations.archives
uploadDescriptor = true
repositories {
if (project.hasProperty('xbibUsername')) {
mavenDeployer {
configuration = configurations.wagon
repository(url: uri(project.property('xbibUrl'))) {
authentication(userName: xbibUsername, privateKey: xbibPrivateKey)
}
}
}
}
}
task sonatypeUpload(type: Upload, dependsOn: build) {
group = 'publish'
configuration = configurations.archives
uploadDescriptor = true
repositories {
if (project.hasProperty('ossrhUsername')) {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: uri(ossrhReleaseUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
snapshotRepository(url: uri(ossrhSnapshotUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
pom.project {
groupId project.group
artifactId project.name
version project.version
name project.name
description projectDescription
packaging 'jar'
inceptionYear '2016'
url scmUrl
organization {
name 'xbib'
url 'http://xbib.org'
}
developers {
developer {
id user
name 'Jörg Prante'
email 'joergprante@gmail.com'
url 'https://github.com/jprante'
}
}
scm {
url scmUrl
connection scmConnection
developerConnection scmDeveloperConnection
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
}
}
}
}
}
nexusStaging {
packageGroup = "org.xbib"
}

View file

@ -1,39 +0,0 @@
tasks.withType(FindBugs) {
ignoreFailures = true
reports {
xml.enabled = false
html.enabled = true
}
}
tasks.withType(Pmd) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
tasks.withType(Checkstyle) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
jacocoTestReport {
reports {
xml.enabled = true
csv.enabled = false
}
}
sonarqube {
properties {
property "sonar.projectName", "${project.group} ${project.name}"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", "src/test/java"
property "sonar.scm.provider", "git"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.junit.reportsPath", "build/test-results/test/"
}
}

Binary file not shown.

View file

@ -1,5 +1,6 @@
#Wed Aug 07 14:17:29 CEST 2019
distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

18
gradlew vendored
View file

@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
@ -28,7 +44,7 @@ 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=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

18
gradlew.bat vendored
View file

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@ -14,7 +30,7 @@ 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=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

View file

@ -1,21 +1,8 @@
configurations {
alpnboot
}
dependencies {
compile project(':oai-common')
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')}"
compile "org.xbib:netty-http-client:${project.property('xbib-netty-http.version')}"
testCompile "io.netty:netty-tcnative-boringssl-static:${project.property('tcnative.version')}"
testCompile "org.xbib:marc:${project.property('xbib-marc.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'
}
systemProperty 'java.util.logging.manager', 'org.apache.logging.log4j.jul.LogManager'
}

View file

@ -1,323 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<property name="groups" value="com,io,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
</module>

View file

@ -1,27 +1,19 @@
package org.xbib.oai.client;
import org.xbib.net.URL;
import org.xbib.oai.OAIConstants;
import org.xbib.oai.OAIRequest;
import org.xbib.oai.util.ResumptionToken;
import org.xbib.oai.util.URIBuilder;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Client OAI request.
*/
public abstract class AbstractOAIRequest implements OAIRequest {
private static final Logger logger = Logger.getLogger(AbstractOAIRequest.class.getName());
private URIBuilder uriBuilder;
private final URL.Builder urlBuilder;
private DateTimeFormatter dateTimeFormatter;
@ -37,33 +29,22 @@ public abstract class AbstractOAIRequest implements OAIRequest {
private boolean retry;
protected AbstractOAIRequest() {
uriBuilder = new URIBuilder();
protected AbstractOAIRequest(URL url) {
this.urlBuilder = URL.builder()
.scheme(url.getScheme())
.host(url.getHost())
.port(url.getPort())
.path(url.getPath());
}
public void setURL(URL url) {
try {
URI uri = url.toURI();
uriBuilder.scheme(uri.getScheme())
.authority(uri.getAuthority())
.path(uri.getPath());
} catch (URISyntaxException e) {
logger.log(Level.WARNING, e.getMessage(), e);
throw new IllegalArgumentException("invalid URI " + url);
}
public URL getURL() {
return urlBuilder.build();
}
public URL getURL() throws MalformedURLException {
return uriBuilder.build().toURL();
}
public String getPath() {
return uriBuilder.buildGetPath();
}
public void addParameter(String name, String value) {
protected void addParameter(String name, String value) {
if (value != null && !value.isEmpty()) {
uriBuilder.addParameter(name, value);
urlBuilder.queryParam(name, value).build();
}
}
@ -144,9 +125,10 @@ public abstract class AbstractOAIRequest implements OAIRequest {
+ "]";
}
class GetRecord extends AbstractOAIRequest {
/*class GetRecord extends AbstractOAIRequest {
public GetRecord() {
super(url);
addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.GET_RECORD);
}
}
@ -154,6 +136,7 @@ public abstract class AbstractOAIRequest implements OAIRequest {
class Identify extends AbstractOAIRequest {
public Identify() {
super(url);
addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.IDENTIFY);
}
}
@ -161,6 +144,7 @@ public abstract class AbstractOAIRequest implements OAIRequest {
class ListIdentifiers extends AbstractOAIRequest {
public ListIdentifiers() {
super(url);
addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_IDENTIFIERS);
}
}
@ -168,6 +152,7 @@ public abstract class AbstractOAIRequest implements OAIRequest {
class ListMetadataFormats extends AbstractOAIRequest {
public ListMetadataFormats() {
super(url);
addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_METADATA_FORMATS);
}
}
@ -175,6 +160,7 @@ public abstract class AbstractOAIRequest implements OAIRequest {
class ListRecordsRequest extends AbstractOAIRequest {
public ListRecordsRequest() {
super(url);
addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_RECORDS);
}
@ -183,7 +169,8 @@ public abstract class AbstractOAIRequest implements OAIRequest {
class ListSetsRequest extends AbstractOAIRequest {
public ListSetsRequest() {
super(url);
addParameter(OAIConstants.VERB_PARAMETER, OAIConstants.LIST_SETS);
}
}
}*/
}

View file

@ -1,9 +1,9 @@
package org.xbib.oai.client;
import org.xbib.helianthus.common.http.AggregatedHttpMessage;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.oai.OAIResponse;
import org.xbib.oai.exceptions.OAIException;
import java.io.IOException;
import java.io.Writer;
/**
@ -11,5 +11,5 @@ import java.io.Writer;
*/
public abstract class AbstractOAIResponse implements OAIResponse {
public abstract void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException;
public abstract void receivedResponse(HttpResponse message, Writer writer) throws OAIException;
}

View file

@ -1,8 +1,7 @@
package org.xbib.oai.client;
import org.xbib.helianthus.client.ClientBuilder;
import org.xbib.helianthus.client.ClientFactory;
import org.xbib.helianthus.client.http.HttpClient;
import org.xbib.net.URL;
import org.xbib.netty.http.client.Client;
import org.xbib.oai.client.getrecord.GetRecordRequest;
import org.xbib.oai.client.identify.IdentifyRequest;
import org.xbib.oai.client.listidentifiers.ListIdentifiersRequest;
@ -11,47 +10,31 @@ 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;
import java.time.Duration;
/**
* OAI client.
*/
public class OAIClient implements AutoCloseable {
private HttpClient client;
private Client client;
private ClientFactory clientFactory;
private final URL url;
private URL url;
public OAIClient setURL(URL url) throws URISyntaxException {
return setURL(url, false);
}
public OAIClient setURL(URL url, boolean trustAlways) throws URISyntaxException {
public OAIClient(URL url) {
this.url = url;
this.clientFactory = ClientFactory.DEFAULT;
this.client = new ClientBuilder("none+" + url.toURI())
.factory(clientFactory)
.defaultResponseTimeout(Duration.ofMinutes(1L)) // maybe not enough for extreme slow archive servers...
.build(HttpClient.class);
return this;
this.client = Client.builder()
.setConnectTimeoutMillis(60 * 1000)
.setReadTimeoutMillis(60 * 1000)
.build();
}
public URL getURL() {
return url;
}
public HttpClient getHttpClient() {
public Client getHttpClient() {
return client;
}
public ClientFactory getFactory() {
return clientFactory;
}
/**
* This verb is used to retrieve information about a repository.
* Some of the information returned is required as part of the OAI-PMH.
@ -60,9 +43,7 @@ public class OAIClient implements AutoCloseable {
* @return identify request
*/
public IdentifyRequest newIdentifyRequest() {
IdentifyRequest request = new IdentifyRequest();
request.setURL(url);
return request;
return new IdentifyRequest(url);
}
/**
@ -72,9 +53,7 @@ public class OAIClient implements AutoCloseable {
* @return list metadata formats request
*/
public ListMetadataFormatsRequest newListMetadataFormatsRequest() {
ListMetadataFormatsRequest request = new ListMetadataFormatsRequest();
request.setURL(getURL());
return request;
return new ListMetadataFormatsRequest(url);
}
/**
@ -83,9 +62,7 @@ public class OAIClient implements AutoCloseable {
* @return list sets request
*/
public ListSetsRequest newListSetsRequest() {
ListSetsRequest request = new ListSetsRequest();
request.setURL(getURL());
return request;
return new ListSetsRequest(url);
}
/**
@ -99,9 +76,7 @@ public class OAIClient implements AutoCloseable {
*
*/
public ListIdentifiersRequest newListIdentifiersRequest() {
ListIdentifiersRequest request = new ListIdentifiersRequest();
request.setURL(getURL());
return request;
return new ListIdentifiersRequest(url);
}
/**
@ -116,9 +91,7 @@ public class OAIClient implements AutoCloseable {
* @return get record request
*/
public GetRecordRequest newGetRecordRequest() {
GetRecordRequest request = new GetRecordRequest();
request.setURL(getURL());
return request;
return new GetRecordRequest(url);
}
/**
@ -132,9 +105,7 @@ public class OAIClient implements AutoCloseable {
* @return list records request
*/
public ListRecordsRequest newListRecordsRequest() {
ListRecordsRequest request = new ListRecordsRequest();
request.setURL(getURL());
return request;
return new ListRecordsRequest(url);
}
public IdentifyRequest resume(IdentifyRequest request, ResumptionToken<?> token) {

View file

@ -1,7 +0,0 @@
package org.xbib.oai.client;
import java.io.IOException;
@SuppressWarnings("serial")
public class TooManyRequestsException extends IOException {
}

View file

@ -1,5 +1,6 @@
package org.xbib.oai.client.getrecord;
import org.xbib.net.URL;
import org.xbib.oai.client.AbstractOAIRequest;
/**
@ -7,8 +8,8 @@ import org.xbib.oai.client.AbstractOAIRequest;
*/
public class GetRecordRequest extends AbstractOAIRequest {
public GetRecordRequest() {
super();
public GetRecordRequest(URL url) {
super(url);
addParameter(VERB_PARAMETER, GET_RECORD);
}
}

View file

@ -1,6 +1,6 @@
package org.xbib.oai.client.getrecord;
import org.xbib.helianthus.common.http.AggregatedHttpMessage;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.oai.client.AbstractOAIResponse;
import java.io.Writer;
@ -11,7 +11,7 @@ import java.io.Writer;
public class GetRecordResponse extends AbstractOAIResponse {
@Override
public void receivedResponse(AggregatedHttpMessage message, Writer writer) {
public void receivedResponse(HttpResponse message, Writer writer) {
// not implemented yet
}
}

View file

@ -1,5 +1,6 @@
package org.xbib.oai.client.identify;
import org.xbib.net.URL;
import org.xbib.oai.client.AbstractOAIRequest;
/**
@ -7,8 +8,8 @@ import org.xbib.oai.client.AbstractOAIRequest;
*/
public class IdentifyRequest extends AbstractOAIRequest {
public IdentifyRequest() {
super();
public IdentifyRequest(URL url) {
super(url);
addParameter(VERB_PARAMETER, IDENTIFY);
}
}

View file

@ -3,8 +3,9 @@ package org.xbib.oai.client.identify;
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.netty.http.common.HttpResponse;
import org.xbib.oai.client.AbstractOAIResponse;
import org.xbib.oai.exceptions.OAIException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -12,6 +13,7 @@ import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -41,15 +43,15 @@ public class IdentifyResponse extends AbstractOAIResponse {
private String compression;
@Override
public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException {
public void receivedResponse(HttpResponse message, Writer writer) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(message.content().toStringUtf8()));
InputSource is = new InputSource(new StringReader(message.getBodyAsString(StandardCharsets.UTF_8)));
Document doc = db.parse(is);
setGranularity(getString("granularity", doc.getDocumentElement()));
} catch (ParserConfigurationException | SAXException e) {
throw new IOException(e);
} catch (ParserConfigurationException | SAXException | IOException e) {
throw new OAIException(e);
}
}

View file

@ -1,5 +1,6 @@
package org.xbib.oai.client.listidentifiers;
import org.xbib.net.URL;
import org.xbib.oai.client.AbstractOAIRequest;
/**
@ -7,8 +8,8 @@ import org.xbib.oai.client.AbstractOAIRequest;
*/
public class ListIdentifiersRequest extends AbstractOAIRequest {
public ListIdentifiersRequest() {
super();
public ListIdentifiersRequest(URL url) {
super(url);
addParameter(VERB_PARAMETER, LIST_IDENTIFIERS);
}
}

View file

@ -1,9 +1,9 @@
package org.xbib.oai.client.listidentifiers;
import org.xbib.helianthus.common.http.AggregatedHttpMessage;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.oai.client.AbstractOAIResponse;
import org.xbib.oai.exceptions.OAIException;
import java.io.IOException;
import java.io.Writer;
/**
@ -12,7 +12,7 @@ import java.io.Writer;
public class ListIdentifiersResponse extends AbstractOAIResponse {
@Override
public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException {
public void receivedResponse(HttpResponse message, Writer writer) throws OAIException {
// not implemented yet
}
}

View file

@ -1,5 +1,6 @@
package org.xbib.oai.client.listmetadataformats;
import org.xbib.net.URL;
import org.xbib.oai.client.AbstractOAIRequest;
/**
@ -7,8 +8,8 @@ import org.xbib.oai.client.AbstractOAIRequest;
*/
public class ListMetadataFormatsRequest extends AbstractOAIRequest {
public ListMetadataFormatsRequest() {
super();
public ListMetadataFormatsRequest(URL url) {
super(url);
addParameter(VERB_PARAMETER, LIST_METADATA_FORMATS);
}
}

View file

@ -1,9 +1,9 @@
package org.xbib.oai.client.listmetadataformats;
import org.xbib.helianthus.common.http.AggregatedHttpMessage;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.oai.client.AbstractOAIResponse;
import org.xbib.oai.exceptions.OAIException;
import java.io.IOException;
import java.io.Writer;
/**
@ -12,7 +12,7 @@ import java.io.Writer;
public class ListMetadataFormatsResponse extends AbstractOAIResponse {
@Override
public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException {
public void receivedResponse(HttpResponse message, Writer writer) throws OAIException {
// not implemented yet
}
}

View file

@ -9,6 +9,8 @@ import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
@ -155,19 +157,17 @@ public class ListRecordsFilterReader extends XMLFilterReader {
try {
header.setDate(Instant.parse(s));
} catch (DateTimeParseException e) {
logger.log(Level.FINEST, e.getMessage(), e);
try {
ZonedDateTime zonedDateTime = ZonedDateTime.parse(s,
DateTimeFormatter.ISO_DATE_TIME);
header.setDate(Instant.from(zonedDateTime));
} catch (DateTimeParseException e1) {
logger.log(Level.FINEST, e1.getMessage(), e1);
try {
ZonedDateTime zonedDateTime = ZonedDateTime.parse(s,
DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate localDate = LocalDate.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.of("UTC"));
header.setDate(Instant.from(zonedDateTime));
} catch (DateTimeParseException e2) {
logger.log(Level.FINEST, e2.getMessage(), e2);
logger.log(Level.WARNING, "unable to parse date: " + s + " reason = " + e2.getMessage());
}
}
}

View file

@ -1,5 +1,6 @@
package org.xbib.oai.client.listrecords;
import org.xbib.net.URL;
import org.xbib.oai.OAIConstants;
import org.xbib.oai.client.AbstractOAIRequest;
import org.xbib.oai.xml.MetadataHandler;
@ -14,8 +15,8 @@ public class ListRecordsRequest extends AbstractOAIRequest {
private List<MetadataHandler> handlers = new LinkedList<>();
public ListRecordsRequest() {
super();
public ListRecordsRequest(URL url) {
super(url);
addParameter(OAIConstants.VERB_PARAMETER, LIST_RECORDS);
}
public ListRecordsRequest addHandler(MetadataHandler handler) {

View file

@ -1,12 +1,12 @@
package org.xbib.oai.client.listrecords;
import io.netty.handler.codec.http.HttpHeaderNames;
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.netty.http.common.HttpResponse;
import org.xbib.oai.client.AbstractOAIResponse;
import org.xbib.oai.client.TooManyRequestsException;
import org.xbib.oai.exceptions.BadVerbException;
import org.xbib.oai.exceptions.TooManyRequestsException;
import org.xbib.oai.exceptions.BadArgumentException;
import org.xbib.oai.exceptions.BadResumptionTokenException;
import org.xbib.oai.exceptions.NoRecordsMatchException;
@ -14,9 +14,9 @@ import org.xbib.oai.exceptions.OAIException;
import org.xbib.oai.util.ResumptionToken;
import org.xml.sax.InputSource;
import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
@ -77,14 +77,14 @@ public class ListRecordsResponse extends AbstractOAIResponse {
}
@Override
public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException {
String content = message.content().toStringUtf8();
int status = message.status().code();
public void receivedResponse(HttpResponse message, Writer writer) throws OAIException {
String content = message.getBodyAsString(StandardCharsets.UTF_8);
int status = message.getStatus().getCode();
if (status == 503) {
long secs = retryAfterMillis / 1000;
if (message.headers() != null) {
if (message.getHeaders() != null) {
for (String retryAfterHeader : RETRY_AFTER_HEADERS) {
String retryAfter = message.headers().get(AsciiString.of(retryAfterHeader));
String retryAfter = message.getHeaders().getHeader(retryAfterHeader);
if (retryAfter == null) {
continue;
}
@ -111,15 +111,19 @@ public class ListRecordsResponse extends AbstractOAIResponse {
return;
}
if (status == 429) {
throw new TooManyRequestsException();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// ignore
}
}
if (status != 200) {
throw new IOException("status = " + status + " response = " + content);
throw new OAIException("status = " + status + " response = " + content);
}
// activate XSLT only if OAI XML content type is returned
String contentType = message.headers().get(HttpHeaderNames.CONTENT_TYPE);
String contentType = message.getHeaders().getHeader(HttpHeaderNames.CONTENT_TYPE);
if (contentType != null && !contentType.startsWith("text/xml")) {
throw new IOException("no XML content type in response: " + contentType);
throw new OAIException("no XML content type in response: " + contentType);
}
this.filterreader = new ListRecordsFilterReader(request, this);
try {
@ -139,11 +143,13 @@ public class ListRecordsResponse extends AbstractOAIResponse {
throw new BadResumptionTokenException(request.getResumptionToken());
} else if ("badArgument".equals(error)) {
throw new BadArgumentException();
} else if ("badVerb".equals(error)) {
throw new BadVerbException(error);
} else if (error != null) {
throw new OAIException(error);
}
} catch (TransformerException t) {
throw new IOException(t);
throw new OAIException(t);
}
}

View file

@ -1,5 +1,6 @@
package org.xbib.oai.client.listsets;
import org.xbib.net.URL;
import org.xbib.oai.client.AbstractOAIRequest;
/**
@ -7,8 +8,8 @@ import org.xbib.oai.client.AbstractOAIRequest;
*/
public class ListSetsRequest extends AbstractOAIRequest {
public ListSetsRequest() {
super();
public ListSetsRequest(URL url) {
super(url);
addParameter(VERB_PARAMETER, LIST_SETS);
}

View file

@ -1,9 +1,9 @@
package org.xbib.oai.client.listsets;
import org.xbib.helianthus.common.http.AggregatedHttpMessage;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.oai.client.AbstractOAIResponse;
import org.xbib.oai.exceptions.OAIException;
import java.io.IOException;
import java.io.Writer;
/**
@ -12,7 +12,7 @@ import java.io.Writer;
public class ListSetsResponse extends AbstractOAIResponse {
@Override
public void receivedResponse(AggregatedHttpMessage message, Writer writer) throws IOException {
public void receivedResponse(HttpResponse message, Writer writer) throws OAIException {
// not implemented yet
}
}

View file

@ -2,15 +2,11 @@ package org.xbib.oai.client;
import static org.junit.Assert.assertTrue;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Ignore;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.junit.Test;
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.net.URL;
import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.client.Request;
import org.xbib.oai.client.identify.IdentifyRequest;
import org.xbib.oai.client.identify.IdentifyResponse;
import org.xbib.oai.client.listrecords.ListRecordsRequest;
@ -21,37 +17,45 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.net.ConnectException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
*/
@Ignore
public class ArxivClientTest {
private static final Logger logger = LogManager.getLogger(ArxivClientTest.class.getName());
private static final Logger logger = Logger.getLogger(ArxivClientTest.class.getName());
@Test
public void testListRecordsArxiv() throws Exception {
try (OAIClient client = new OAIClient().setURL(new URL("http://export.arxiv.org/oai2"))) {
public void testListRecordsArxiv() {
final URL url = URL.create("http://export.arxiv.org/oai2/");
try (OAIClient client = new OAIClient(url)) {
IdentifyRequest identifyRequest = client.newIdentifyRequest();
HttpClient httpClient = client.getHttpClient();
AggregatedHttpMessage response = httpClient.execute(HttpHeaders.of(HttpMethod.GET, identifyRequest.getPath())
.set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get();
Client httpClient = client.getHttpClient();
IdentifyResponse identifyResponse = new IdentifyResponse();
identifyResponse.receivedResponse(response, new StringWriter());
Request request = Request.get()
.url(identifyRequest.getURL())
.addHeader(HttpHeaderNames.ACCEPT.toString(), "utf-8")
.build()
.setResponseListener(resp -> {
logger.log(Level.INFO,
" body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
StringWriter sw = new StringWriter();
identifyResponse.receivedResponse(resp, sw);
});
httpClient.execute(request).get();
String granularity = identifyResponse.getGranularity();
logger.info("granularity = {}", granularity);
logger.log(Level.INFO, "granularity = " + granularity);
DateTimeFormatter dateTimeFormatter = "YYYY-MM-DD".equals(granularity) ?
DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("GMT")) : null;
// ArXiv wants us to wait 20 secs between *every* HTTP request, so we must wait here
logger.info("waiting 20 seconds");
logger.log(Level.INFO,"waiting 20 seconds");
Thread.sleep(20 * 1000L);
ListRecordsRequest listRecordsRequest = client.newListRecordsRequest();
listRecordsRequest.setDateTimeFormatter(dateTimeFormatter);
@ -66,40 +70,43 @@ public class ArxivClientTest {
try {
listRecordsRequest.addHandler(handler);
ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest);
logger.info("sending {}", listRecordsRequest.getPath());
response = httpClient.execute(HttpHeaders.of(HttpMethod.GET, listRecordsRequest.getPath())
.set(HttpHeaderNames.ACCEPT, "utf-8")).aggregate().get();
logger.debug("response headers = {} resumption-token = {}",
response.headers(), listRecordsResponse.getResumptionToken());
listRecordsResponse.receivedResponse(response, fileWriter);
logger.log(Level.INFO,"sending " + listRecordsRequest.getURL());
request = Request.get()
.url(listRecordsRequest.getURL())
.addHeader(HttpHeaderNames.ACCEPT.toString(), "utf-8")
.build()
.setResponseListener(resp -> {
listRecordsResponse.receivedResponse(resp, fileWriter);
logger.log(Level.FINE, "response headers = " + resp.getHeaders() +
" resumption-token = " + listRecordsResponse.getResumptionToken());
});
httpClient.execute(request).get();
listRecordsRequest = client.resume(listRecordsRequest, listRecordsResponse.getResumptionToken());
} catch (IOException e) {
logger.error(e.getMessage(), e);
logger.log(Level.SEVERE, e.getMessage(), e);
listRecordsRequest = null;
}
}
fileWriter.close();
logger.info("count={}", handler.count());
logger.log(Level.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;
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
class Handler extends SimpleMetadataHandler {
static class Handler extends SimpleMetadataHandler {
final AtomicLong count = new AtomicLong(0L);
@Override
public void startDocument() {
logger.debug("start doc");
logger.log(Level.FINE, "start doc");
}
@Override
public void endDocument() {
logger.debug("end doc");
logger.log(Level.FINE, "end doc");
count.incrementAndGet();
}

View file

@ -1,64 +1,65 @@
package org.xbib.oai.client;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.junit.Ignore;
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.net.URL;
import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.client.Request;
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 org.xbib.oai.exceptions.OAIException;
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;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
*/
public class BundeskunsthalleTest {
private static final Logger logger = LogManager.getLogger(BundeskunsthalleTest.class.getName());
private static final Logger logger = Logger.getLogger(BundeskunsthalleTest.class.getName());
@Test
@Ignore // takes too long time and creates files
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)) {
URL url = URL.create("http://www.bundeskunsthalle.de/cgi-bin/bib/oai-pmh");
try (OAIClient oaiClient = new OAIClient(url)) {
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();
Client httpClient = oaiClient.getHttpClient();
IdentifyResponse identifyResponse = new IdentifyResponse();
Request request = Request.get()
.url(url.resolve(identifyRequest.getURL()))
.addHeader(HttpHeaderNames.ACCEPT.toString(), "utf-8")
.build()
.setResponseListener(resp -> {
StringWriter sw = new StringWriter();
identifyResponse.receivedResponse(resp, sw);
});
httpClient.execute(request).get();
/*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;
/*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);
logger.log(Level.INFO, "granularity = " + granularity);
DateTimeFormatter dateTimeFormatter = "YYYY-MM-DD".equals(granularity) ?
DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("GMT")) : null;
ListRecordsRequest listRecordsRequest = oaiClient.newListRecordsRequest();
@ -72,43 +73,51 @@ public class BundeskunsthalleTest {
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();
logger.log(Level.INFO,"sending " + listRecordsRequest.getURL());
StringWriter sw = new StringWriter();
request = Request.get()
.url(url.resolve(listRecordsRequest.getURL()))
.addHeader(HttpHeaderNames.ACCEPT.toString(), "utf-8")
.build()
.setResponseListener(resp -> {
try {
Marc.builder()
.setInputStream(resp.getBodyAsStream())
.setCharset(StandardCharsets.UTF_8)
.setContentHandler(new MarcContentHandler()
.setFormat("MarcXML")
.setType("Bibliographic")
.addNamespace("http://www.loc.gov/MARC21/slim")
.setMarcListener(writer))
.build()
.xmlReader().parse();
} catch (IOException e) {
throw new OAIException(e);
}
listRecordsResponse.receivedResponse(resp, sw);
logger.log(Level.FINE, "response headers = " + resp.getHeaders() +
" resumption-token = {}" + listRecordsResponse.getResumptionToken());
});
httpClient.execute(request).get();
// follow a maximum of 10 HTTP redirects
max = 10;
/*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);
logger.log(Level.SEVERE, 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;
} catch (Exception e) {
logger.log(Level.WARNING, e.getMessage(), e);
}
}
}

View file

@ -2,15 +2,12 @@ package org.xbib.oai.client;
import static org.junit.Assert.assertEquals;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.junit.Ignore;
import org.junit.Test;
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.net.URL;
import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.client.Request;
import org.xbib.oai.client.identify.IdentifyRequest;
import org.xbib.oai.client.listrecords.ListRecordsRequest;
import org.xbib.oai.client.listrecords.ListRecordsResponse;
@ -19,11 +16,11 @@ import org.xbib.oai.xml.SimpleMetadataHandler;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@ -31,21 +28,29 @@ import java.util.concurrent.atomic.AtomicLong;
@Ignore
public class DNBClientTest {
private static final Logger logger = LogManager.getLogger(DNBClientTest.class.getName());
private static final Logger logger = Logger.getLogger(DNBClientTest.class.getName());
@Test
public void testIdentify() throws Exception {
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());
AggregatedHttpMessage response = httpClient.get(request.getPath()).aggregate().get();
logger.info("{}", response.content().toStringUtf8());
public void testIdentify() {
URL url = URL.create("http://services.dnb.de/oai/repository");
try (OAIClient client = new OAIClient(url)) {
IdentifyRequest identifyRequest = client.newIdentifyRequest();
Client httpClient = client.getHttpClient();
assertEquals("/oai/repository?verb=Identify", identifyRequest.getURL().toString());
Request request = Request.get()
.url(url.resolve(identifyRequest.getURL()))
.build()
.setResponseListener(resp -> logger.log(Level.INFO, resp.getBodyAsString(StandardCharsets.UTF_8)));
httpClient.execute(request).get();
} catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
@Test
public void testListRecordsDNB() throws Exception {
try (OAIClient client = new OAIClient().setURL(new URL("http://services.dnb.de/oai/repository"))){
public void testListRecordsDNB() {
URL url = URL.create("http://services.dnb.de/oai/repository");
try (OAIClient client = new OAIClient(url)) {
ListRecordsRequest listRecordsRequest = client.newListRecordsRequest();
listRecordsRequest.setFrom(Instant.parse("2016-01-01T00:00:00Z"));
listRecordsRequest.setUntil(Instant.parse("2016-01-10T00:00:00Z"));
@ -54,44 +59,42 @@ public class DNBClientTest {
Handler handler = new Handler();
File file = File.createTempFile("dnb-bib-pica.", ".xml");
file.deleteOnExit();
FileWriter sw = new FileWriter(file);
FileWriter fileWriter = new FileWriter(file);
while (listRecordsRequest != null) {
try {
ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest);
listRecordsRequest.addHandler(handler);
HttpClient httpClient = client.getHttpClient();
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);
Request request = Request.get()
.url(url.resolve(listRecordsRequest.getURL()))
.addHeader(HttpHeaderNames.ACCEPT.toString(), "utf-8")
.build()
.setResponseListener(resp -> listRecordsResponse.receivedResponse(resp, fileWriter));
client.getHttpClient().execute(request).get();
listRecordsRequest = client.resume(listRecordsRequest, listRecordsResponse.getResumptionToken());
} catch (IOException e) {
logger.error(e.getMessage(), e);
logger.log(Level.SEVERE, e.getMessage(), e);
listRecordsRequest = null;
}
}
sw.close();
logger.info("count={}", handler.count());
} catch (ConnectException | ExecutionException e) {
logger.warn("skipped, can not connect");
} catch (IOException e) {
logger.warn("skipped, HTTP exception");
fileWriter.close();
logger.log(Level.INFO, "count=" + handler.count());
} catch (Exception e) {
logger.log(Level.SEVERE, "skipped, HTTP exception");
}
}
class Handler extends SimpleMetadataHandler {
static class Handler extends SimpleMetadataHandler {
final AtomicLong count = new AtomicLong(0L);
@Override
public void startDocument() {
logger.debug("start doc");
logger.log(Level.FINE, "start doc");
}
@Override
public void endDocument() {
logger.debug("end doc");
logger.log(Level.FINE, "end doc");
count.incrementAndGet();
}

View file

@ -1,15 +1,11 @@
package org.xbib.oai.client;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.junit.Ignore;
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.net.URL;
import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.client.Request;
import org.xbib.oai.client.identify.IdentifyRequest;
import org.xbib.oai.client.identify.IdentifyResponse;
import org.xbib.oai.client.listrecords.ListRecordsRequest;
@ -18,47 +14,41 @@ import org.xbib.oai.xml.SimpleMetadataHandler;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.net.ConnectException;
import java.net.URI;
import java.net.URL;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
*/
public class DOAJClientTest {
private static final Logger logger = LogManager.getLogger(DOAJClientTest.class.getName());
private static final Logger logger = Logger.getLogger(DOAJClientTest.class.getName());
@Test
@Ignore // takes too long time
public void testListRecordsDOAJ() throws Exception {
// will redirect to https://doaj.org/oai
try (OAIClient oaiClient = new OAIClient().setURL(new URL("http://doaj.org/oai"), true)) {
public void testListRecordsDOAJ() {
URL url = URL.create("https://doaj.org/oai");
try (OAIClient oaiClient = new OAIClient(url)) {
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();
}
Client httpClient = oaiClient.getHttpClient();
IdentifyResponse identifyResponse = new IdentifyResponse();
String content = response.content().toStringUtf8();
logger.debug("identifyResponse = {}", content);
identifyResponse.receivedResponse(response, new StringWriter());
Request request = Request.get()
.url(url.resolve(identifyRequest.getURL()))
.addHeader(HttpHeaderNames.ACCEPT.toString(), "utf-8")
.build()
.setResponseListener(resp -> {
StringWriter sw = new StringWriter();
identifyResponse.receivedResponse(resp, sw);
});
httpClient.execute(request).get();
String granularity = identifyResponse.getGranularity();
logger.info("granularity = {}", granularity);
logger.log(Level.INFO, "granularity = " + granularity);
DateTimeFormatter dateTimeFormatter = "YYYY-MM-DD".equals(granularity) ?
DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.of("GMT")) : null;
ListRecordsRequest listRecordsRequest = oaiClient.newListRecordsRequest();
@ -70,56 +60,41 @@ public class DOAJClientTest {
File file = File.createTempFile("doaj.", ".xml");
file.deleteOnExit();
FileWriter fileWriter = new FileWriter(file);
ListRecordsResponse listRecordsResponse = null;
while (listRecordsRequest != null) {
try {
logger.debug("request = {}", listRecordsRequest);
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();
// 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();
}
listRecordsResponse.receivedResponse(response, fileWriter);
listRecordsRequest = oaiClient.resume(listRecordsRequest, listRecordsResponse.getResumptionToken());
} catch (TooManyRequestsException e) {
logger.error(e.getMessage(), e);
Thread.sleep(10000L);
listRecordsRequest = oaiClient.resume(listRecordsRequest, listRecordsResponse.getResumptionToken());
} catch (IOException e) {
logger.error(e.getMessage(), e);
listRecordsRequest = null;
}
ListRecordsResponse listRecordsResponse = new ListRecordsResponse(listRecordsRequest);
listRecordsRequest.addHandler(handler);
logger.log(Level.INFO,"sending " + listRecordsRequest.getURL());
request = Request.get()
.url(url.resolve(listRecordsRequest.getURL()))
.addHeader(HttpHeaderNames.ACCEPT.toString(), "utf-8")
.build()
.setResponseListener(resp -> {
listRecordsResponse.receivedResponse(resp, fileWriter);
logger.log(Level.FINE, "response headers = " + resp.getHeaders() +
" resumption-token = {}" + listRecordsResponse.getResumptionToken());
});
httpClient.execute(request).get();
listRecordsRequest = oaiClient.resume(listRecordsRequest, listRecordsResponse.getResumptionToken());
}
fileWriter.close();
logger.info("count={}", handler.count());
} catch (ConnectException | ExecutionException e) {
logger.warn("skipped, can not connect, exception is:", e);
} catch (InterruptedException | IOException e) {
throw e;
logger.log(Level.INFO, "count = " + handler.count());
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
class Handler extends SimpleMetadataHandler {
static class Handler extends SimpleMetadataHandler {
final AtomicLong count = new AtomicLong(0L);
@Override
public void startDocument() {
logger.debug("start doc");
logger.log(Level.FINE, "start doc");
}
@Override
public void endDocument() {
logger.debug("end doc");
logger.log(Level.FINE, "end doc");
count.incrementAndGet();
}

View file

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{ABSOLUTE}][%-5p][%-25c][%t] %m%n"/>
</Console>
</appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</configuration>

View file

@ -0,0 +1,5 @@
handlers = java.util.logging.ConsoleHandler
.level = INFO
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format = %1$tFT%1$tT.%1$tL%1$tz [%4$-11s] [%3$s] %5$s %6$s%n

View file

@ -1,323 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<property name="groups" value="com,io,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
</module>

View file

@ -1,11 +1,9 @@
package org.xbib.oai.exceptions;
import java.io.IOException;
/**
*
*/
public class OAIException extends IOException {
public class OAIException extends RuntimeException {
private static final long serialVersionUID = -1890146067179892744L;

View file

@ -0,0 +1,8 @@
package org.xbib.oai.exceptions;
@SuppressWarnings("serial")
public class TooManyRequestsException extends OAIException {
public TooManyRequestsException(String message) {
super(message);
}
}

View file

@ -1,4 +1,4 @@
dependencies {
compile project(':oai-common')
compile "org.xbib.helianthus:helianthus-server:${project.property('helianthus.version')}"
}

View file

@ -1,323 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<property name="groups" value="com,io,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
</module>