initial commit of 42.7.4.0
This commit is contained in:
commit
698d755934
647 changed files with 131167 additions and 0 deletions
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
/.settings
|
||||
/.classpath
|
||||
/.project
|
||||
/.gradle
|
||||
**/data
|
||||
**/work
|
||||
**/logs
|
||||
**/.idea
|
||||
**/target
|
||||
**/out
|
||||
**/build
|
||||
.DS_Store
|
||||
*.iml
|
||||
*~
|
34
build.gradle
Normal file
34
build.gradle
Normal file
|
@ -0,0 +1,34 @@
|
|||
plugins {
|
||||
id 'maven-publish'
|
||||
id 'signing'
|
||||
id "io.github.gradle-nexus.publish-plugin" version "2.0.0-rc-1"
|
||||
}
|
||||
|
||||
wrapper {
|
||||
gradleVersion = libs.versions.gradle.get()
|
||||
distributionType = Wrapper.DistributionType.BIN
|
||||
}
|
||||
|
||||
ext {
|
||||
user = 'joerg'
|
||||
name = 'pgjdbc'
|
||||
description = 'Fork of pgjdbc for simplified build and Java 21+'
|
||||
inceptionYear = '2024'
|
||||
url = 'https://xbib.org/' + user + '/' + name
|
||||
scmUrl = 'https://xbib.org/' + user + '/' + name
|
||||
scmConnection = 'scm:git:git://xbib.org/' + user + '/' + name + '.git'
|
||||
scmDeveloperConnection = 'scm:git:ssh://forgejo@xbib.org:' + user + '/' + name + '.git'
|
||||
issueManagementSystem = 'Forgejo'
|
||||
issueManagementUrl = ext.scmUrl + '/issues'
|
||||
licenseName = 'The Apache License, Version 2.0'
|
||||
licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply from: rootProject.file('gradle/compile/java.gradle')
|
||||
apply from: rootProject.file('gradle/test/junit5.gradle')
|
||||
apply from: rootProject.file('gradle/repositories/maven.gradle')
|
||||
apply from: rootProject.file('gradle/publish/maven.gradle')
|
||||
}
|
||||
apply from: rootProject.file('gradle/publish/sonatype.gradle')
|
||||
apply from: rootProject.file('gradle/publish/forgejo.gradle')
|
4
gradle.properties
Normal file
4
gradle.properties
Normal file
|
@ -0,0 +1,4 @@
|
|||
group = org.xbib.jdbc
|
||||
name = pgjdbc
|
||||
version = 42.7.4.0
|
||||
|
30
gradle/compile/java.gradle
Normal file
30
gradle/compile/java.gradle
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
apply plugin: 'java-library'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
modularity.inferModulePath.set(true)
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes('Implementation-Version': project.version)
|
||||
}
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.fork = true
|
||||
options.forkOptions.jvmArgs += ['-Duser.language=en','-Duser.country=US']
|
||||
options.compilerArgs.add('-Xlint:all')
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
55
gradle/documentation/asciidoc.gradle
Normal file
55
gradle/documentation/asciidoc.gradle
Normal file
|
@ -0,0 +1,55 @@
|
|||
apply plugin: 'org.xbib.gradle.plugin.asciidoctor'
|
||||
|
||||
configurations {
|
||||
asciidoclet
|
||||
}
|
||||
|
||||
dependencies {
|
||||
asciidoclet "org.asciidoctor:asciidoclet:${project.property('asciidoclet.version')}"
|
||||
}
|
||||
|
||||
|
||||
asciidoctor {
|
||||
backends 'html5'
|
||||
outputDir = file("${rootProject.projectDir}/docs")
|
||||
separateOutputDirs = false
|
||||
attributes 'source-highlighter': 'coderay',
|
||||
idprefix: '',
|
||||
idseparator: '-',
|
||||
toc: 'left',
|
||||
doctype: 'book',
|
||||
icons: 'font',
|
||||
encoding: 'utf-8',
|
||||
sectlink: true,
|
||||
sectanchors: true,
|
||||
linkattrs: true,
|
||||
imagesdir: 'img',
|
||||
stylesheet: "${projectDir}/src/docs/asciidoc/css/foundation.css"
|
||||
}
|
||||
|
||||
|
||||
/*javadoc {
|
||||
options.docletpath = configurations.asciidoclet.files.asType(List)
|
||||
options.doclet = 'org.asciidoctor.Asciidoclet'
|
||||
//options.overview = "src/docs/asciidoclet/overview.adoc"
|
||||
options.addStringOption "-base-dir", "${projectDir}"
|
||||
options.addStringOption "-attribute",
|
||||
"name=${project.name},version=${project.version},title-link=https://github.com/xbib/${project.name}"
|
||||
configure(options) {
|
||||
noTimestamp = true
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/*javadoc {
|
||||
options.docletpath = configurations.asciidoclet.files.asType(List)
|
||||
options.doclet = 'org.asciidoctor.Asciidoclet'
|
||||
options.overview = "${rootProject.projectDir}/src/docs/asciidoclet/overview.adoc"
|
||||
options.addStringOption "-base-dir", "${projectDir}"
|
||||
options.addStringOption "-attribute",
|
||||
"name=${project.name},version=${project.version},title-link=https://github.com/xbib/${project.name}"
|
||||
options.destinationDirectory(file("${projectDir}/docs/javadoc"))
|
||||
configure(options) {
|
||||
noTimestamp = true
|
||||
}
|
||||
}*/
|
13
gradle/ide/idea.gradle
Normal file
13
gradle/ide/idea.gradle
Normal file
|
@ -0,0 +1,13 @@
|
|||
apply plugin: 'idea'
|
||||
|
||||
idea {
|
||||
module {
|
||||
outputDir file('build/classes/java/main')
|
||||
testOutputDir file('build/classes/java/test')
|
||||
}
|
||||
project {
|
||||
jdkName = '17'
|
||||
languageLevel = '17'
|
||||
vcs = 'Git'
|
||||
}
|
||||
}
|
16
gradle/publish/forgejo.gradle
Normal file
16
gradle/publish/forgejo.gradle
Normal file
|
@ -0,0 +1,16 @@
|
|||
if (project.hasProperty('forgeJoToken')) {
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://xbib.org/api/packages/joerg/maven'
|
||||
credentials(HttpHeaderCredentials) {
|
||||
name = "Authorization"
|
||||
value = "token ${project.property('forgeJoToken')}"
|
||||
}
|
||||
authentication {
|
||||
header(HttpHeaderAuthentication)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
gradle/publish/ivy.gradle
Normal file
27
gradle/publish/ivy.gradle
Normal file
|
@ -0,0 +1,27 @@
|
|||
apply plugin: 'ivy-publish'
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
ivy {
|
||||
url = "https://xbib.org/repo"
|
||||
}
|
||||
}
|
||||
publications {
|
||||
ivy(IvyPublication) {
|
||||
from components.java
|
||||
descriptor {
|
||||
license {
|
||||
name = 'The Apache License, Version 2.0'
|
||||
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||
}
|
||||
author {
|
||||
name = 'Jörg Prante'
|
||||
url = 'http://example.com/users/jane'
|
||||
}
|
||||
descriptor.description {
|
||||
text = rootProject.ext.description
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
51
gradle/publish/maven.gradle
Normal file
51
gradle/publish/maven.gradle
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
publishing {
|
||||
publications {
|
||||
"${project.name}"(MavenPublication) {
|
||||
from components.java
|
||||
pom {
|
||||
artifactId = project.name
|
||||
name = project.name
|
||||
description = rootProject.ext.description
|
||||
url = rootProject.ext.url
|
||||
inceptionYear = rootProject.ext.inceptionYear
|
||||
packaging = 'jar'
|
||||
organization {
|
||||
name = 'xbib'
|
||||
url = 'https://xbib.org'
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id = 'jprante'
|
||||
name = 'Jörg Prante'
|
||||
email = 'joergprante@gmail.com'
|
||||
url = 'https://xbib.org/joerg'
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url = rootProject.ext.scmUrl
|
||||
connection = rootProject.ext.scmConnection
|
||||
developerConnection = rootProject.ext.scmDeveloperConnection
|
||||
}
|
||||
issueManagement {
|
||||
system = rootProject.ext.issueManagementSystem
|
||||
url = rootProject.ext.issueManagementUrl
|
||||
}
|
||||
licenses {
|
||||
license {
|
||||
name = rootProject.ext.licenseName
|
||||
url = rootProject.ext.licenseUrl
|
||||
distribution = 'repo'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (project.hasProperty("signing.keyId")) {
|
||||
apply plugin: 'signing'
|
||||
signing {
|
||||
sign publishing.publications."${project.name}"
|
||||
}
|
||||
}
|
12
gradle/publish/sonatype.gradle
Normal file
12
gradle/publish/sonatype.gradle
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) {
|
||||
nexusPublishing {
|
||||
repositories {
|
||||
sonatype {
|
||||
username = project.property('ossrhUsername')
|
||||
password = project.property('ossrhPassword')
|
||||
packageGroup = "org.xbib"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
gradle/quality/checkstyle.gradle
Normal file
19
gradle/quality/checkstyle.gradle
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
apply plugin: 'checkstyle'
|
||||
|
||||
tasks.withType(Checkstyle) {
|
||||
ignoreFailures = true
|
||||
reports {
|
||||
xml.getRequired().set(true)
|
||||
html.getRequired().set(true)
|
||||
}
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
configFile = rootProject.file('gradle/quality/checkstyle.xml')
|
||||
ignoreFailures = true
|
||||
showViolations = true
|
||||
checkstyleMain {
|
||||
source = sourceSets.main.allSource
|
||||
}
|
||||
}
|
333
gradle/quality/checkstyle.xml
Normal file
333
gradle/quality/checkstyle.xml
Normal file
|
@ -0,0 +1,333 @@
|
|||
<?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="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value=".*(Example|Test|module-info)(\$.*)?"/>
|
||||
</module>
|
||||
|
||||
<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="tokens" value="IMPORT, STATIC_IMPORT"/> -->
|
||||
<property name="separated" value="false"/>
|
||||
<property name="groups" value="*"/>
|
||||
<!-- <property name="option" value="above"/> -->
|
||||
<property name="sortStaticImportsAlphabetically" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="CustomImportOrder">
|
||||
<!-- <property name="customImportOrderRules" value="THIRD_PARTY_PACKAGE###SPECIAL_IMPORTS###STANDARD_JAVA_PACKAGE###STATIC"/> -->
|
||||
<!-- <property name="specialImportsRegExp" value="^javax\."/> -->
|
||||
<!-- <property name="standardPackageRegExp" value="^java\."/> -->
|
||||
<property name="sortImportsInGroupAlphabetically" value="true"/>
|
||||
<property name="separateLineBetweenGroups" value="false"/>
|
||||
</module>
|
||||
|
||||
<!--
|
||||
|
||||
JAVADOC CHECKS
|
||||
|
||||
-->
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
|
||||
<module name="JavadocMethod">
|
||||
<property name="accessModifiers" value="protected"/>
|
||||
<property name="severity" value="warning"/>
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" 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="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 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>
|
||||
|
11
gradle/quality/cyclonedx.gradle
Normal file
11
gradle/quality/cyclonedx.gradle
Normal file
|
@ -0,0 +1,11 @@
|
|||
cyclonedxBom {
|
||||
includeConfigs = [ 'runtimeClasspath' ]
|
||||
skipConfigs = [ 'compileClasspath', 'testCompileClasspath' ]
|
||||
projectType = "library"
|
||||
schemaVersion = "1.4"
|
||||
destination = file("build/reports")
|
||||
outputName = "bom"
|
||||
outputFormat = "json"
|
||||
includeBomSerialNumber = true
|
||||
componentVersion = "2.0.0"
|
||||
}
|
17
gradle/quality/pmd.gradle
Normal file
17
gradle/quality/pmd.gradle
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
apply plugin: 'pmd'
|
||||
|
||||
tasks.withType(Pmd) {
|
||||
ignoreFailures = true
|
||||
reports {
|
||||
xml.getRequired().set(true)
|
||||
html.getRequired().set(true)
|
||||
}
|
||||
}
|
||||
|
||||
pmd {
|
||||
ignoreFailures = true
|
||||
consoleOutput = false
|
||||
toolVersion = "6.51.0"
|
||||
ruleSetFiles = rootProject.files('gradle/quality/pmd/category/java/bestpractices.xml')
|
||||
}
|
10
gradle/quality/sonarqube.gradle
Normal file
10
gradle/quality/sonarqube.gradle
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
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/"
|
||||
}
|
||||
}
|
15
gradle/quality/spotbugs.gradle
Normal file
15
gradle/quality/spotbugs.gradle
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
apply plugin: 'com.github.spotbugs'
|
||||
|
||||
spotbugs {
|
||||
//effort = "max"
|
||||
//reportLevel = "low"
|
||||
ignoreFailures = true
|
||||
}
|
||||
|
||||
spotbugsMain {
|
||||
reports {
|
||||
xml.getRequired().set(false)
|
||||
html.getRequired().set(true)
|
||||
}
|
||||
}
|
4
gradle/repositories/maven.gradle
Normal file
4
gradle/repositories/maven.gradle
Normal file
|
@ -0,0 +1,4 @@
|
|||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
26
gradle/test/junit5.gradle
Normal file
26
gradle/test/junit5.gradle
Normal file
|
@ -0,0 +1,26 @@
|
|||
dependencies {
|
||||
testImplementation testLibs.junit.jupiter.api
|
||||
testImplementation testLibs.junit.jupiter.params
|
||||
testImplementation testLibs.hamcrest
|
||||
testRuntimeOnly testLibs.junit.jupiter.engine
|
||||
testRuntimeOnly testLibs.junit.jupiter.platform.launcher
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
failFast = true
|
||||
systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties'
|
||||
testLogging {
|
||||
events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED'
|
||||
showStandardStreams = true
|
||||
}
|
||||
afterSuite { desc, result ->
|
||||
if (!desc.parent) {
|
||||
println "\nTest result: ${result.resultType}"
|
||||
println "Test summary: ${result.testCount} tests, " +
|
||||
"${result.successfulTestCount} succeeded, " +
|
||||
"${result.failedTestCount} failed, " +
|
||||
"${result.skippedTestCount} skipped"
|
||||
}
|
||||
}
|
||||
}
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
249
gradlew
vendored
Executable file
249
gradlew
vendored
Executable file
|
@ -0,0 +1,249 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
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
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
92
gradlew.bat
vendored
Normal file
92
gradlew.bat
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
3
pgjdbc/build.gradle
Normal file
3
pgjdbc/build.gradle
Normal file
|
@ -0,0 +1,3 @@
|
|||
dependencies {
|
||||
api project(':scram-client')
|
||||
}
|
25
pgjdbc/src/main/java/module-info.java
Normal file
25
pgjdbc/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
import java.sql.Driver;
|
||||
|
||||
module org.xbib.jdbc.pgjdbc {
|
||||
requires java.logging;
|
||||
requires java.management;
|
||||
requires java.naming;
|
||||
requires transitive java.sql;
|
||||
requires transitive java.security.jgss;
|
||||
requires org.xbib.scram.client;
|
||||
exports org.postgresql;
|
||||
exports org.postgresql.copy;
|
||||
exports org.postgresql.core;
|
||||
exports org.postgresql.core.v3;
|
||||
exports org.postgresql.fastpath;
|
||||
exports org.postgresql.jdbc;
|
||||
exports org.postgresql.jdbc2;
|
||||
exports org.postgresql.largeobject;
|
||||
exports org.postgresql.replication;
|
||||
exports org.postgresql.replication.fluent;
|
||||
exports org.postgresql.replication.fluent.logical;
|
||||
exports org.postgresql.replication.fluent.physical;
|
||||
exports org.postgresql.util;
|
||||
exports org.postgresql.xml;
|
||||
provides Driver with org.postgresql.Driver;
|
||||
}
|
796
pgjdbc/src/main/java/org/postgresql/Driver.java
Normal file
796
pgjdbc/src/main/java/org/postgresql/Driver.java
Normal file
|
@ -0,0 +1,796 @@
|
|||
/*
|
||||
* Copyright (c) 2003, PostgreSQL Global Development Group
|
||||
* See the LICENSE file in the project root for more information.
|
||||
*/
|
||||
|
||||
package org.postgresql;
|
||||
|
||||
import org.postgresql.jdbc.PgConnection;
|
||||
import org.postgresql.jdbc.ResourceLock;
|
||||
import org.postgresql.jdbcurlresolver.PgPassParser;
|
||||
import org.postgresql.jdbcurlresolver.PgServiceConfParser;
|
||||
import org.postgresql.util.DriverInfo;
|
||||
import org.postgresql.util.GT;
|
||||
import org.postgresql.util.HostSpec;
|
||||
import org.postgresql.util.PGPropertyUtil;
|
||||
import org.postgresql.util.PSQLException;
|
||||
import org.postgresql.util.PSQLState;
|
||||
import org.postgresql.util.SharedTimer;
|
||||
import org.postgresql.util.URLCoder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.DriverPropertyInfo;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* <p>The Java SQL framework allows for multiple database drivers. Each driver should supply a class
|
||||
* that implements the Driver interface</p>
|
||||
*
|
||||
* <p>The DriverManager will try to load as many drivers as it can find and then for any given
|
||||
* connection request, it will ask each driver in turn to try to connect to the target URL.</p>
|
||||
*
|
||||
* <p>It is strongly recommended that each Driver class should be small and standalone so that the
|
||||
* Driver class can be loaded and queried without bringing in vast quantities of supporting code.</p>
|
||||
*
|
||||
* <p>When a Driver class is loaded, it should create an instance of itself and register it with the
|
||||
* DriverManager. This means that a user can load and register a driver by doing
|
||||
* Class.forName("foo.bah.Driver")</p>
|
||||
*
|
||||
* @see org.postgresql.PGConnection
|
||||
* @see java.sql.Driver
|
||||
*/
|
||||
@SuppressWarnings("try")
|
||||
public class Driver implements java.sql.Driver {
|
||||
|
||||
private static Driver registeredDriver;
|
||||
private static final Logger PARENT_LOGGER = Logger.getLogger("org.postgresql");
|
||||
private static final Logger LOGGER = Logger.getLogger("org.postgresql.Driver");
|
||||
private static final SharedTimer SHARED_TIMER = new SharedTimer();
|
||||
|
||||
static {
|
||||
try {
|
||||
// moved the registerDriver from the constructor to here
|
||||
// because some clients call the driver themselves (I know, as
|
||||
// my early jdbc work did - and that was based on other examples).
|
||||
// Placing it here, means that the driver is registered once only.
|
||||
register();
|
||||
} catch (SQLException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to retrieve default properties from classloader resource
|
||||
// properties files.
|
||||
private Properties defaultProperties;
|
||||
|
||||
private final ResourceLock lock = new ResourceLock();
|
||||
|
||||
public Driver() {
|
||||
}
|
||||
|
||||
private Properties getDefaultProperties() throws IOException {
|
||||
try (ResourceLock ignore = lock.obtain()) {
|
||||
if (defaultProperties != null) {
|
||||
return defaultProperties;
|
||||
}
|
||||
|
||||
// Make sure we load properties with the maximum possible privileges.
|
||||
try {
|
||||
defaultProperties =
|
||||
doPrivileged(new PrivilegedExceptionAction<Properties>() {
|
||||
@Override
|
||||
public Properties run() throws IOException {
|
||||
return loadDefaultProperties();
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
Exception ex = e.getException();
|
||||
if (ex instanceof IOException) {
|
||||
throw (IOException) ex;
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof IOException) {
|
||||
throw (IOException) e;
|
||||
}
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
if (e instanceof Error) {
|
||||
throw (Error) e;
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return defaultProperties;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws Throwable {
|
||||
try {
|
||||
Class<?> accessControllerClass = Class.forName("java.security.AccessController");
|
||||
Method doPrivileged = accessControllerClass.getMethod("doPrivileged",
|
||||
PrivilegedExceptionAction.class);
|
||||
return (T) doPrivileged.invoke(null, action);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return action.run();
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
private Properties loadDefaultProperties() throws IOException {
|
||||
Properties merged = new Properties();
|
||||
|
||||
try {
|
||||
PGProperty.USER.set(merged, System.getProperty("user.name"));
|
||||
} catch (SecurityException se) {
|
||||
// We're just trying to set a default, so if we can't
|
||||
// it's not a big deal.
|
||||
}
|
||||
|
||||
// If we are loaded by the bootstrap classloader, getClassLoader()
|
||||
// may return null. In that case, try to fall back to the system
|
||||
// classloader.
|
||||
//
|
||||
// We should not need to catch SecurityException here as we are
|
||||
// accessing either our own classloader, or the system classloader
|
||||
// when our classloader is null. The ClassLoader javadoc claims
|
||||
// neither case can throw SecurityException.
|
||||
ClassLoader cl = getClass().getClassLoader();
|
||||
if (cl == null) {
|
||||
LOGGER.log(Level.FINE, "Can't find our classloader for the Driver; "
|
||||
+ "attempt to use the system class loader");
|
||||
cl = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
|
||||
if (cl == null) {
|
||||
LOGGER.log(Level.WARNING, "Can't find a classloader for the Driver; not loading driver "
|
||||
+ "configuration from org/postgresql/driverconfig.properties");
|
||||
return merged; // Give up on finding defaults.
|
||||
}
|
||||
|
||||
LOGGER.log(Level.FINE, "Loading driver configuration via classloader {0}", cl);
|
||||
|
||||
// When loading the driver config files we don't want settings found
|
||||
// in later files in the classpath to override settings specified in
|
||||
// earlier files. To do this we've got to read the returned
|
||||
// Enumeration into temporary storage.
|
||||
ArrayList<URL> urls = new ArrayList<>();
|
||||
Enumeration<URL> urlEnum = cl.getResources("org/postgresql/driverconfig.properties");
|
||||
while (urlEnum.hasMoreElements()) {
|
||||
urls.add(urlEnum.nextElement());
|
||||
}
|
||||
|
||||
for (int i = urls.size() - 1; i >= 0; i--) {
|
||||
URL url = urls.get(i);
|
||||
LOGGER.log(Level.FINE, "Loading driver configuration from: {0}", url);
|
||||
InputStream is = url.openStream();
|
||||
merged.load(is);
|
||||
is.close();
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Try to make a database connection to the given URL. The driver should return "null" if it
|
||||
* realizes it is the wrong kind of driver to connect to the given URL. This will be common, as
|
||||
* when the JDBC driverManager is asked to connect to a given URL, it passes the URL to each
|
||||
* loaded driver in turn.</p>
|
||||
*
|
||||
* <p>The driver should raise an SQLException if it is the right driver to connect to the given URL,
|
||||
* but has trouble connecting to the database.</p>
|
||||
*
|
||||
* <p>The java.util.Properties argument can be used to pass arbitrary string tag/value pairs as
|
||||
* connection arguments.</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>user - (required) The user to connect as</li>
|
||||
* <li>password - (optional) The password for the user</li>
|
||||
* <li>ssl -(optional) Use SSL when connecting to the server</li>
|
||||
* <li>readOnly - (optional) Set connection to read-only by default</li>
|
||||
* <li>charSet - (optional) The character set to be used for converting to/from
|
||||
* the database to unicode. If multibyte is enabled on the server then the character set of the
|
||||
* database is used as the default, otherwise the jvm character encoding is used as the default.
|
||||
* This value is only used when connecting to a 7.2 or older server.</li>
|
||||
* <li>loglevel - (optional) Enable logging of messages from the driver. The value is an integer
|
||||
* from 0 to 2 where: OFF = 0, INFO =1, DEBUG = 2 The output is sent to
|
||||
* DriverManager.getPrintWriter() if set, otherwise it is sent to System.out.</li>
|
||||
* <li>compatible - (optional) This is used to toggle between different functionality
|
||||
* as it changes across different releases of the jdbc driver code. The values here are versions
|
||||
* of the jdbc client and not server versions. For example in 7.1 get/setBytes worked on
|
||||
* LargeObject values, in 7.2 these methods were changed to work on bytea values. This change in
|
||||
* functionality could be disabled by setting the compatible level to be "7.1", in which case the
|
||||
* driver will revert to the 7.1 functionality.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Normally, at least "user" and "password" properties should be included in the properties. For a
|
||||
* list of supported character encoding , see
|
||||
* http://java.sun.com/products/jdk/1.2/docs/guide/internat/encoding.doc.html Note that you will
|
||||
* probably want to have set up the Postgres database itself to use the same encoding, with the
|
||||
* {@code -E <encoding>} argument to createdb.</p>
|
||||
*
|
||||
* <p>Our protocol takes the forms:</p>
|
||||
*
|
||||
* <pre>
|
||||
* jdbc:postgresql://host:port/database?param1=val1&...
|
||||
* </pre>
|
||||
*
|
||||
* @param url the URL of the database to connect to
|
||||
* @param info a list of arbitrary tag/value pairs as connection arguments
|
||||
* @return a connection to the URL or null if it isnt us
|
||||
* @exception SQLException if a database access error occurs or the url is
|
||||
* {@code null}
|
||||
* @see java.sql.Driver#connect
|
||||
*/
|
||||
@Override
|
||||
public Connection connect(String url, Properties info) throws SQLException {
|
||||
if (url == null) {
|
||||
throw new SQLException("url is null");
|
||||
}
|
||||
// get defaults
|
||||
Properties defaults;
|
||||
|
||||
if (!url.startsWith("jdbc:postgresql:")) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
defaults = getDefaultProperties();
|
||||
} catch (IOException ioe) {
|
||||
throw new PSQLException(GT.tr("Error loading default settings from driverconfig.properties"),
|
||||
PSQLState.UNEXPECTED_ERROR, ioe);
|
||||
}
|
||||
|
||||
// override defaults with provided properties
|
||||
Properties props = new Properties(defaults);
|
||||
if (info != null) {
|
||||
Set<String> e = info.stringPropertyNames();
|
||||
for (String propName : e) {
|
||||
String propValue = info.getProperty(propName);
|
||||
if (propValue == null) {
|
||||
throw new PSQLException(
|
||||
GT.tr("Properties for the driver contains a non-string value for the key ")
|
||||
+ propName,
|
||||
PSQLState.UNEXPECTED_ERROR);
|
||||
}
|
||||
props.setProperty(propName, propValue);
|
||||
}
|
||||
}
|
||||
// parse URL and add more properties
|
||||
if ((props = parseURL(url, props)) == null) {
|
||||
throw new PSQLException(
|
||||
GT.tr("Unable to parse URL {0}", url),
|
||||
PSQLState.UNEXPECTED_ERROR);
|
||||
}
|
||||
try {
|
||||
|
||||
LOGGER.log(Level.FINE, "Connecting with URL: {0}", url);
|
||||
|
||||
// Enforce login timeout, if specified, by running the connection
|
||||
// attempt in a separate thread. If we hit the timeout without the
|
||||
// connection completing, we abandon the connection attempt in
|
||||
// the calling thread, but the separate thread will keep trying.
|
||||
// Eventually, the separate thread will either fail or complete
|
||||
// the connection; at that point we clean up the connection if
|
||||
// we managed to establish one after all. See ConnectThread for
|
||||
// more details.
|
||||
long timeout = timeout(props);
|
||||
if (timeout <= 0) {
|
||||
return makeConnection(url, props);
|
||||
}
|
||||
|
||||
ConnectThread ct = new ConnectThread(url, props);
|
||||
Thread thread = new Thread(ct, "PostgreSQL JDBC driver connection thread");
|
||||
thread.setDaemon(true); // Don't prevent the VM from shutting down
|
||||
thread.start();
|
||||
return ct.getResult(timeout);
|
||||
} catch (PSQLException ex1) {
|
||||
LOGGER.log(Level.FINE, "Connection error: ", ex1);
|
||||
// re-throw the exception, otherwise it will be caught next, and a
|
||||
// org.postgresql.unusual error will be returned instead.
|
||||
throw ex1;
|
||||
} catch (Exception ex2) {
|
||||
if ("java.security.AccessControlException".equals(ex2.getClass().getName())) {
|
||||
// java.security.AccessControlException has been deprecated for removal, so compare the class name
|
||||
throw new PSQLException(
|
||||
GT.tr(
|
||||
"Your security policy has prevented the connection from being attempted. You probably need to grant the connect java.net.SocketPermission to the database server host and port that you wish to connect to."),
|
||||
PSQLState.UNEXPECTED_ERROR, ex2);
|
||||
}
|
||||
LOGGER.log(Level.FINE, "Unexpected connection error: ", ex2);
|
||||
throw new PSQLException(
|
||||
GT.tr(
|
||||
"Something unusual has occurred to cause the driver to fail. Please report this exception."),
|
||||
PSQLState.UNEXPECTED_ERROR, ex2);
|
||||
}
|
||||
}
|
||||