Skip to content

Commit c3b6fd9

Browse files
committed
added java package
1 parent fe91051 commit c3b6fd9

23 files changed

Lines changed: 3043 additions & 10 deletions

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ updates:
2121
directory: "/packages/rust" # Location of package manifests
2222
schedule:
2323
interval: "weekly"
24+
- package-ecosystem: "maven" # See documentation for possible values
25+
directory: "/packages/java" # Location of package manifests
26+
schedule:
27+
interval: "weekly"

.github/workflows/ci.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ jobs:
3939
with:
4040
python-version: "3.14"
4141

42+
- name: Setup Java
43+
# actions/setup-java@v5
44+
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654
45+
with:
46+
distribution: temurin
47+
java-version: "25"
48+
cache: maven
49+
4250
- name: Install dependencies
4351
run: pnpm install --frozen-lockfile
4452

.github/workflows/release.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ jobs:
6161
with:
6262
python-version: "3.14"
6363

64+
- name: Setup Java
65+
# actions/setup-java@v5
66+
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654
67+
with:
68+
distribution: temurin
69+
java-version: "25"
70+
cache: maven
71+
6472
- name: Install dependencies
6573
run: pnpm install --frozen-lockfile
6674

@@ -114,14 +122,17 @@ jobs:
114122
- name: Rust crate dry-run
115123
run: cargo publish --manifest-path packages/rust/Cargo.toml --locked --dry-run
116124

125+
- name: Build Java package
126+
run: mvn -q -f packages/java/pom.xml -DskipTests package
127+
117128
- name: Build Python package
118129
run: |
119130
python -m pip install build==1.5.0
120131
python -m build packages/python
121132
122133
- name: Commit version bump
123134
run: |
124-
git add packages/js/package.json packages/python/pyproject.toml packages/rust/Cargo.toml packages/rust/Cargo.lock
135+
git add packages/js/package.json packages/java/pom.xml packages/python/pyproject.toml packages/rust/Cargo.toml packages/rust/Cargo.lock
125136
git commit -m "release v${{ steps.version.outputs.version }}"
126137
127138
- name: Push version commit

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SAP HANA, Athena, Spanner, Google Cloud Storage, Azure Blob, Azure Data Lake
1010
Storage, Azure Files, Azure Cosmos DB, Business Central, TallyPrime, Amazon S3,
1111
and local file paths.
1212

13-
This repository contains JavaScript, Go, Python, and Rust implementations,
13+
This repository contains JavaScript, Go, Python, Rust, and Java implementations,
1414
shared Connparse Definition Specification (CPDS) YAML definitions, and shared
1515
compatibility fixtures.
1616

@@ -20,6 +20,7 @@ compatibility fixtures.
2020
- Go: `github.com/clidey/connparse/packages/go`
2121
- Python: `connparse`
2222
- Rust: `connparse`
23+
- Java: `io.github.clidey:connparse`
2324

2425
## Repository Layout
2526

@@ -35,14 +36,16 @@ packages/
3536
go/ Go implementation
3637
python/ Python implementation
3738
rust/ Rust crate implementation
39+
java/ Java implementation
3840
```
3941

4042
## Install
4143

4244
The JavaScript package has one runtime dependency: `yaml`, used to load CPDS
4345
definition files. The Go package uses `github.com/goccy/go-yaml` for the same
44-
CPDS loader API. The Python parser uses the standard library at runtime. The Rust
45-
crate uses `serde` and `serde_json` for the shared JSON-shaped contract.
46+
CPDS loader API. The Python and Java parsers use the standard library at
47+
runtime. The Rust crate uses `serde` and `serde_json` for the shared
48+
JSON-shaped contract.
4649

4750
```bash
4851
npm install @clidey/connparse
@@ -60,6 +63,7 @@ pnpm test
6063
pnpm test:go
6164
pnpm test:python
6265
pnpm test:rust
66+
pnpm test:java
6367
pnpm check:package
6468
```
6569

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
"verify:definitions": "node tools/verify-definitions.mjs",
1010
"verify:definitions:strict": "node tools/verify-definitions.mjs --strict-suggestions",
1111
"sync:versions": "node tools/sync-versions.mjs",
12-
"test": "pnpm test:js && pnpm test:go && pnpm test:python && pnpm test:rust",
12+
"test": "pnpm test:js && pnpm test:go && pnpm test:python && pnpm test:rust && pnpm test:java",
1313
"test:js": "pnpm --filter @clidey/connparse test",
1414
"test:go": "cd packages/go && GOCACHE=$(pwd)/../../.cache/go-build GOMODCACHE=$(pwd)/../../.cache/go-mod go test ./...",
1515
"test:python": "PYTHONPATH=packages/python/src python3 -m unittest discover -s packages/python/tests",
1616
"test:rust": "cd packages/rust && CARGO_TARGET_DIR=../../.cache/cargo-target CARGO_HOME=../../.cache/cargo-home cargo test",
17-
"check": "pnpm check:versions && pnpm verify:definitions:strict && pnpm check:schemas && pnpm check:conformance && pnpm check:generated && pnpm check:tools && pnpm check:js && pnpm check:go && pnpm check:python && pnpm check:rust",
17+
"test:java": "node tools/test-java.mjs",
18+
"check": "pnpm check:versions && pnpm verify:definitions:strict && pnpm check:schemas && pnpm check:conformance && pnpm check:generated && pnpm check:tools && pnpm check:js && pnpm check:go && pnpm check:python && pnpm check:rust && pnpm check:java",
1819
"check:conformance": "node tools/conformance-runner.mjs --quiet",
1920
"check:generated": "node tools/generate-definitions.mjs --check",
2021
"check:package": "node tools/package-consumption-test.mjs",
@@ -24,7 +25,8 @@
2425
"check:js": "pnpm --filter @clidey/connparse check",
2526
"check:go": "cd packages/go && GOCACHE=$(pwd)/../../.cache/go-build GOMODCACHE=$(pwd)/../../.cache/go-mod go test ./...",
2627
"check:python": "python3 -m compileall -q packages/python/src packages/python/tests packages/python/scripts && PYTHONPATH=packages/python/src node tools/conformance-runner.mjs --skip-coverage -- python3 packages/python/scripts/conformance.py",
27-
"check:rust": "cd packages/rust && CARGO_TARGET_DIR=../../.cache/cargo-target CARGO_HOME=../../.cache/cargo-home cargo fmt --check && CARGO_TARGET_DIR=../../.cache/cargo-target CARGO_HOME=../../.cache/cargo-home cargo test"
28+
"check:rust": "cd packages/rust && CARGO_TARGET_DIR=../../.cache/cargo-target CARGO_HOME=../../.cache/cargo-home cargo fmt --check && CARGO_TARGET_DIR=../../.cache/cargo-target CARGO_HOME=../../.cache/cargo-home cargo test",
29+
"check:java": "node tools/test-java.mjs"
2830
},
2931
"devDependencies": {}
3032
}

packages/java/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# connparse for Java
2+
3+
Connparse parses connection strings from databases, caches, object storage,
4+
files, and cloud systems into one structured object.
5+
6+
It supports PostgreSQL, MySQL, MariaDB, SQLite, DuckDB, ClickHouse, Redis,
7+
Memcached, Elasticsearch, MongoDB, CockroachDB, QuestDB, YugabyteDB, TiDB,
8+
Valkey, Dragonfly, OpenSearch, FerretDB, ElastiCache, DocumentDB, SQL Server,
9+
Oracle, Snowflake, Cassandra, BigQuery, Redshift, Aurora, Neo4j, Trino,
10+
Databricks, DynamoDB, StarRocks, SAP HANA, Athena, Spanner, Google Cloud
11+
Storage, Azure Blob, Azure Data Lake Storage, Azure Files, Azure Cosmos DB,
12+
Business Central, TallyPrime, Amazon S3, and local file paths.
13+
14+
CPDS means Connparse Definition Specification. The Java package embeds generated
15+
definitions from the shared CPDS YAML files in `specs/definitions`.
16+
17+
## Usage
18+
19+
```java
20+
import io.github.clidey.connparse.Connparse;
21+
import io.github.clidey.connparse.ParseOptions;
22+
import io.github.clidey.connparse.ParseResult;
23+
24+
ParseResult result = Connparse.parse(
25+
"postgres://user:pass@localhost:5432/app?sslmode=require"
26+
);
27+
28+
if (!result.ok) {
29+
System.err.println(result.errors);
30+
} else {
31+
System.out.println(result.value.safe);
32+
System.out.println(result.value.resource.name);
33+
}
34+
```
35+
36+
The parsed value contains the same top-level fields as the other packages:
37+
38+
```json
39+
{
40+
"scheme": "postgres",
41+
"type": "database",
42+
"authority": { "host": "localhost", "port": 5432 },
43+
"resource": { "type": "database", "name": "app" },
44+
"path": "",
45+
"query": { "sslmode": "require" },
46+
"fragment": null,
47+
"credentials": { "username": "user", "password": "pass" },
48+
"options": {},
49+
"raw": "postgres://user:pass@localhost:5432/app?sslmode=require",
50+
"safe": "postgres://user:***@localhost:5432/app?sslmode=require"
51+
}
52+
```
53+
54+
## Provider Hints
55+
56+
Some inputs need a provider because the string itself does not identify one:
57+
58+
```java
59+
ParseResult result = Connparse.parse(
60+
"host=db.example.com dbname=app user=alice",
61+
new ParseOptions().withProvider("postgres")
62+
);
63+
```
64+
65+
## Strict Mode
66+
67+
By default, unknown query parameters become warnings. Strict mode rejects them:
68+
69+
```java
70+
ParseResult result = Connparse.parse(
71+
"postgres://localhost/app?unexpected=1",
72+
new ParseOptions().withStrict(true)
73+
);
74+
```
75+
76+
## Development
77+
78+
From the repository root:
79+
80+
```bash
81+
pnpm test:java
82+
pnpm check:java
83+
pnpm generate:definitions
84+
```

packages/java/pom.xml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>io.github.clidey</groupId>
7+
<artifactId>connparse</artifactId>
8+
<version>0.3.0</version>
9+
<packaging>jar</packaging>
10+
11+
<name>connparse</name>
12+
<description>Parse database connection strings, DSNs, URLs, file paths, and cloud storage URIs.</description>
13+
<url>https://github.com/clidey/connparse</url>
14+
15+
<licenses>
16+
<license>
17+
<name>Apache License 2.0</name>
18+
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
19+
</license>
20+
</licenses>
21+
22+
<developers>
23+
<developer>
24+
<id>clidey</id>
25+
<name>Clidey</name>
26+
</developer>
27+
</developers>
28+
29+
<scm>
30+
<connection>scm:git:https://github.com/clidey/connparse.git</connection>
31+
<developerConnection>scm:git:ssh://git@github.com/clidey/connparse.git</developerConnection>
32+
<url>https://github.com/clidey/connparse</url>
33+
</scm>
34+
35+
<properties>
36+
<maven.compiler.release>17</maven.compiler.release>
37+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
38+
</properties>
39+
</project>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package io.github.clidey.connparse;
2+
3+
import java.util.LinkedHashMap;
4+
import java.util.Map;
5+
6+
public final class Address {
7+
public final String scheme;
8+
public final String type;
9+
public final Map<String, Object> authority;
10+
public final Resource resource;
11+
public final String path;
12+
public final Map<String, Object> query;
13+
public final String fragment;
14+
public final Map<String, String> credentials;
15+
public final Map<String, Object> options;
16+
public final String raw;
17+
public final String safe;
18+
19+
public Address(
20+
String scheme,
21+
String type,
22+
Map<String, Object> authority,
23+
Resource resource,
24+
String path,
25+
Map<String, Object> query,
26+
String fragment,
27+
Map<String, String> credentials,
28+
Map<String, Object> options,
29+
String raw,
30+
String safe) {
31+
this.scheme = scheme == null ? "" : scheme;
32+
this.type = type == null ? "unknown" : type;
33+
this.authority = new LinkedHashMap<>(authority == null ? Map.of() : authority);
34+
this.resource = resource == null ? new Resource("none", null) : resource;
35+
this.path = path == null ? "" : path;
36+
this.query = new LinkedHashMap<>(query == null ? Map.of() : query);
37+
this.fragment = fragment;
38+
this.credentials = new LinkedHashMap<>(credentials == null ? Map.of() : credentials);
39+
this.options = new LinkedHashMap<>(options == null ? Map.of() : options);
40+
this.raw = raw == null ? "" : raw;
41+
this.safe = safe == null ? "" : safe;
42+
}
43+
44+
public Map<String, Object> toMap() {
45+
Map<String, Object> output = new LinkedHashMap<>();
46+
output.put("scheme", scheme);
47+
output.put("type", type);
48+
output.put("authority", authority);
49+
output.put("resource", resource.toMap());
50+
output.put("path", path);
51+
output.put("query", query);
52+
output.put("fragment", fragment);
53+
output.put("credentials", credentials);
54+
output.put("options", options);
55+
output.put("raw", raw);
56+
output.put("safe", safe);
57+
return output;
58+
}
59+
60+
public static final class Resource {
61+
public final String type;
62+
public final String name;
63+
64+
public Resource(String type, String name) {
65+
this.type = type == null ? "none" : type;
66+
this.name = name;
67+
}
68+
69+
public Map<String, Object> toMap() {
70+
Map<String, Object> output = new LinkedHashMap<>();
71+
output.put("type", type);
72+
output.put("name", name);
73+
return output;
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)