Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 195 additions & 0 deletions .github/workflows/java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
name: java

on:
push:
branches: main
paths:
- 'java/**'
- '.github/workflows/java.yml'
pull_request:
paths:
- 'java/**'
- '.github/workflows/java.yml'

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

defaults:
run:
working-directory: java

jobs:
findChangedJavaFiles:
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
isJavaFilesChanged: ${{ steps.setIsJavaFilesChangedOutput.outputs.isJavaFilesChanged }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Get changed files using defaults
id: changed-files
uses: tj-actions/changed-files@v47
- name: Set output isJavaFilesChanged
id: setIsJavaFilesChangedOutput
run: |
isJavaFilesChanged='false'
echo "Changed files: ${{ steps.changed-files.outputs.all_changed_files }}"
for changedFile in ${{ steps.changed-files.outputs.all_changed_files }}; do
if [[ $changedFile == java/*.java ]] || [[ $changedFile == java/*.xml ]] || [[ $changedFile == java/* ]] || [[ $changedFile == .github/workflows/java.yml ]]; then
echo "isJavaFilesChanged='true'"
isJavaFilesChanged='true'
break
fi
done
echo "isJavaFilesChanged=${isJavaFilesChanged}" >> $GITHUB_OUTPUT
echo "isJavaFilesChanged: ${isJavaFilesChanged}"

build:
needs: [findChangedJavaFiles]
if: ${{ needs.findChangedJavaFiles.outputs.isJavaFilesChanged == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B compile --file pom.xml

test:
needs: [findChangedJavaFiles, build]
if: ${{ needs.findChangedJavaFiles.outputs.isJavaFilesChanged == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
matrix:
java: ['11', '17', '21']
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
cache: maven
- name: Test with Maven
run: mvn -B test --file pom.xml

format:
needs: [findChangedJavaFiles]
if: ${{ needs.findChangedJavaFiles.outputs.isJavaFilesChanged == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Check formatting with Spotless
run: mvn -B spotless:check --file pom.xml

publishToMavenCentral:
needs: [test, format, findChangedJavaFiles]
if: ${{ needs.findChangedJavaFiles.outputs.isJavaFilesChanged == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
cache: maven
server-id: ossrh
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Check if version already published
id: version-check
run: |
PACKAGE_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
PACKAGE_GROUP=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout)
PACKAGE_ARTIFACT=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout)
echo "Package: $PACKAGE_GROUP:$PACKAGE_ARTIFACT:$PACKAGE_VERSION"

# Check if version exists on Maven Central
URL="https://repo1.maven.org/maven2/$(echo $PACKAGE_GROUP | tr '.' '/')/$PACKAGE_ARTIFACT/$PACKAGE_VERSION/"
if curl --head --silent --fail "$URL" > /dev/null 2>&1; then
echo "Version $PACKAGE_VERSION already exists on Maven Central"
echo "should_publish=false" >> $GITHUB_OUTPUT
else
echo "Version $PACKAGE_VERSION does not exist on Maven Central"
echo "should_publish=true" >> $GITHUB_OUTPUT
fi
- name: Publish to Maven Central
if: steps.version-check.outputs.should_publish == 'true'
run: mvn -B deploy -Prelease --file pom.xml
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

publishRelease:
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [publishToMavenCentral]
if: ${{ needs.findChangedJavaFiles.outputs.isJavaFilesChanged == 'true' && needs.publishToMavenCentral.result == 'success' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Check if GitHub release already exists
id: release-check
run: |
PACKAGE_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
TAG_NAME="java_$PACKAGE_VERSION"
echo "Checking if release $TAG_NAME already exists"

# Check if release exists
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
echo "Release $TAG_NAME already exists"
echo "should_create_release=false" >> $GITHUB_OUTPUT
else
echo "Release $TAG_NAME does not exist"
echo "should_create_release=true" >> $GITHUB_OUTPUT
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub release
if: steps.release-check.outputs.should_create_release == 'true'
run: |
PACKAGE_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
PACKAGE_GROUP=$(mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout)
PACKAGE_ARTIFACT=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout)

# Create release with consistent tag format: java_version
gh release create "java_${PACKAGE_VERSION}" \
--title "[Java] $PACKAGE_VERSION" \
--notes "https://central.sonatype.com/artifact/$PACKAGE_GROUP/$PACKAGE_ARTIFACT/$PACKAGE_VERSION"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,6 @@ rust/target/
target/venv/
.venv/
venv/

# java
java/target/
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
| [![Actions Status](https://github.com/link-foundation/links-notation/workflows/rust/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=rust) | [![Crates.io Version and Downloads count](https://img.shields.io/crates/v/links-notation?label=crates.io&style=flat)](https://crates.io/crates/links-notation) | **[Rust](rust/README.md)** |
| [![Actions Status](https://github.com/link-foundation/links-notation/workflows/csharp/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=csharp) | [![NuGet Version and Downloads count](https://img.shields.io/nuget/v/Link.Foundation.Links.Notation?label=nuget&style=flat)](https://www.nuget.org/packages/Link.Foundation.Links.Notation) | **[C#](csharp/README.md)** |
| [![Actions Status](https://github.com/link-foundation/links-notation/workflows/python/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=python) | [![PyPI Version and Downloads count](https://img.shields.io/pypi/v/links-notation?label=pypi&style=flat)](https://pypi.org/project/links-notation/) | **[Python](python/README.md)** |
| [![Actions Status](https://github.com/link-foundation/links-notation/workflows/java/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=java) | [![Maven Central Version](https://img.shields.io/maven-central/v/io.github.link-foundation/links-notation?label=maven&style=flat)](https://central.sonatype.com/artifact/io.github.link-foundation/links-notation) | **[Java](java/README.md)** |

[![Gitpod](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/link-foundation/links-notation)
[![Open in GitHub Codespaces](https://img.shields.io/badge/GitHub%20Codespaces-Open-181717?logo=github)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=link-foundation/links-notation)
Expand Down Expand Up @@ -56,6 +57,14 @@ parser = Parser()
links = parser.parse("papa (lovesMama: loves mama)")
```

### Java

```java
import io.github.linkfoundation.linksnotation.Parser;
Parser parser = new Parser();
List<Link> links = parser.parse("papa (lovesMama: loves mama)");
```

## Examples

### Links notation (lino)
Expand Down Expand Up @@ -137,23 +146,25 @@ language-specific documentation:
- **[JavaScript README](js/README.md)** - Modern web development guide
- **[Rust README](rust/README.md)** - High-performance parsing guide
- **[Python README](python/README.md)** - Python package guide
- **[Java README](java/README.md)** - Java/Maven package guide

Additional resources:

- [Test Case Comparison](TEST_CASE_COMPARISON.md) - Comprehensive test coverage comparison across all 4 language implementations
- [Test Case Comparison](TEST_CASE_COMPARISON.md) - Comprehensive test coverage comparison across language implementations
- [PDF Documentation](https://link-foundation.github.io/links-notation/csharp/Link.Foundation.Links.Notation.pdf)
\- Complete reference for offline reading
- [Links Theory 0.0.2](https://habr.com/en/articles/895896) - Theoretical
foundation that Links Notation fully supports

## Test Coverage & Implementation Parity

All four language implementations (C#, JavaScript, Rust, Python) maintain **equivalent core functionality** with comprehensive test coverage:
All five language implementations (C#, JavaScript, Rust, Python, Java) maintain **equivalent core functionality** with comprehensive test coverage:

- **Python**: 108 tests across 10 categories - All passing ✅
- **JavaScript**: 109 tests across 11 categories - All passing ✅
- **Rust**: 110 tests across 11 categories - All passing ✅
- **C#**: 111 tests across 12 categories - All passing ✅
- **Java**: 117 tests across 7 categories - All passing ✅

**90+ tests match identically** across all languages, verifying functional equivalence. See [TEST_CASE_COMPARISON.md](TEST_CASE_COMPARISON.md) for the complete cross-language test comparison with links to source code.

Expand Down
10 changes: 10 additions & 0 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
| [![Состояние Actions](https://github.com/link-foundation/links-notation/workflows/rust/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=rust) | [![Версия Crates.io и количество загрузок](https://img.shields.io/crates/v/links-notation?label=crates.io&style=flat)](https://crates.io/crates/links-notation) | **[Rust](rust/README.ru.md)** |
| [![Состояние Actions](https://github.com/link-foundation/links-notation/workflows/csharp/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=csharp) | [![Версия NuGet пакета и количество загрузок](https://img.shields.io/nuget/v/Link.Foundation.Links.Notation?label=nuget&style=flat)](https://www.nuget.org/packages/Link.Foundation.Links.Notation) | **[C#](csharp/README.ru.md)** |
| [![Состояние Actions](https://github.com/link-foundation/links-notation/workflows/python/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=python) | [![Версия PyPI и количество загрузок](https://img.shields.io/pypi/v/links-notation?label=pypi&style=flat)](https://pypi.org/project/links-notation/) | **[Python](python/README.ru.md)** |
| [![Состояние Actions](https://github.com/link-foundation/links-notation/workflows/java/badge.svg)](https://github.com/link-foundation/links-notation/actions?workflow=java) | [![Версия Maven Central](https://img.shields.io/maven-central/v/io.github.link-foundation/links-notation?label=maven&style=flat)](https://central.sonatype.com/artifact/io.github.link-foundation/links-notation) | **[Java](java/README.ru.md)** |

[![Gitpod](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/link-foundation/links-notation)
[![Open in GitHub Codespaces](https://img.shields.io/badge/GitHub%20Codespaces-Open-181717?logo=github)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=link-foundation/links-notation)
Expand Down Expand Up @@ -56,6 +57,14 @@ parser = Parser()
links = parser.parse("папа (любитМаму: любит маму)")
```

### Java

```java
import io.github.linkfoundation.linksnotation.Parser;
Parser parser = new Parser();
List<Link> links = parser.parse("папа (любитМаму: любит маму)");
```

## Примеры

### Нотация связей
Expand Down Expand Up @@ -123,6 +132,7 @@ links = parser.parse("папа (любитМаму: любит маму)")
- **[README Rust](rust/README.ru.md)** - Руководство по
высокопроизводительному парсингу
- **[README Python](python/README.ru.md)** - Руководство по работе с пакетом Python
- **[README Java](java/README.ru.md)** - Руководство по работе с пакетом Java/Maven

Дополнительные ресурсы:

Expand Down
Loading