From f0ce2ed37b1bd5dcdd6e3a023030fe4c92328af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 19:23:19 +0100 Subject: [PATCH 01/26] Update version string to '4.0.0-SNAPSHOT'. --- buildSrc/src/main/kotlin/Env.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Env.kt b/buildSrc/src/main/kotlin/Env.kt index 2b5f9cd1..7ace38ce 100644 --- a/buildSrc/src/main/kotlin/Env.kt +++ b/buildSrc/src/main/kotlin/Env.kt @@ -52,7 +52,7 @@ object Env { * Information about the library and author. */ object JPX { - const val VERSION = "3.1.0" + const val VERSION = "4.0.0-SNAPSHOT" const val ID = "jpx" const val NAME = "jpx" const val GROUP = "io.jenetics" From 75d5d7e67228876e83dbb307c8779f7c275d9232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 19:24:27 +0100 Subject: [PATCH 02/26] Remove Java 17 from build. --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 455229cc..3d920fc2 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [ ubuntu-latest, macos-latest ] - java-version: [ 17, 21 ] + java-version: [ 21 ] steps: - uses: actions/checkout@v2 From b48a91e7965ff2a10fa717b2fe6728fa6580b247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 19:26:43 +0100 Subject: [PATCH 03/26] #174: Update to Java 21. --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7376957f..d32a8111 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -68,8 +68,8 @@ gradle.projectsEvaluated { plugins.withType { configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } configure { From f35146e6d5ace46b24f4454d24d6b89be1d49fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 19:32:11 +0100 Subject: [PATCH 04/26] #174: Update compiler warning flags. --- build.gradle.kts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index d32a8111..d5164cff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -239,13 +239,18 @@ fun xlint(): String { "empty", "exports", "finally", + "lossy-conversions", "module", "opens", "overrides", "rawtypes", "removal", - "serial", + // "serial", "static", + "strictfp", + "synchronization", + "text-blocks", + "this-escape", "try", "unchecked", "varargs" From 62a2ede11a931e8ec62f3db853b6260a20f9031b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 19:37:37 +0100 Subject: [PATCH 05/26] #174: Extract version catalog to toml file. --- gradle/libs.versions.toml | 13 +++++++++++++ settings.gradle.kts | 14 -------------- 2 files changed, 13 insertions(+), 14 deletions(-) create mode 100644 gradle/libs.versions.toml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..9d42c88d --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,13 @@ +[plugins] + +jmh = { id = "me.champeau.jmh", version = "0.7.2" } + +[libraries] + +assertj = "org.assertj:assertj-core:3.24.2" +commons-math = "org.apache.commons:commons-math3:3.6.1" +equalsverifier = "nl.jqno.equalsverifier:equalsverifier:3.15.3" +guava = "com.google.guava:guava:32.1.3-jre" +prngine = "io.jenetics:prngine:2.0.0" +rxjava = "io.reactivex.rxjava2:rxjava:2.2.21" +testng = "org.testng:testng:7.8.0" diff --git a/settings.gradle.kts b/settings.gradle.kts index 821a0555..8363af47 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -30,20 +30,6 @@ pluginManagement { } } -dependencyResolutionManagement { - versionCatalogs { - create("libs") { - library("assertj", "org.assertj:assertj-core:3.24.2") - library("commons-math", "org.apache.commons:commons-math3:3.6.1") - library("equalsverifier", "nl.jqno.equalsverifier:equalsverifier:3.15.3") - library("guava", "com.google.guava:guava:32.1.3-jre") - library("prngine", "io.jenetics:prngine:2.0.0") - library("rxjava", "io.reactivex.rxjava2:rxjava:2.2.21") - library("testng", "org.testng:testng:7.8.0") - } - } -} - rootProject.name = "jpx" // The JPX projects. From eaa3bfe3716103e7d27d44f11e92653f37fd37fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 19:51:43 +0100 Subject: [PATCH 06/26] #174: Use Javadoc code snippets. --- build.gradle.kts | 35 +- buildSrc/resources/javadoc/stylesheet.css | 881 ------------------ .../java/io/jenetics/gradle/Colorizer.java | 363 -------- .../io/jenetics/gradle/ColorizerTask.java | 63 -- .../java/io/jenetics/gradle/package-info.java | 26 - jpx/src/main/java/io/jenetics/jpx/Bounds.java | 4 +- jpx/src/main/java/io/jenetics/jpx/Email.java | 6 +- .../main/java/io/jenetics/jpx/Filters.java | 16 +- jpx/src/main/java/io/jenetics/jpx/GPX.java | 88 +- jpx/src/main/java/io/jenetics/jpx/Length.java | 4 +- .../main/java/io/jenetics/jpx/Metadata.java | 16 +- jpx/src/main/java/io/jenetics/jpx/Route.java | 16 +- jpx/src/main/java/io/jenetics/jpx/Speed.java | 4 +- jpx/src/main/java/io/jenetics/jpx/Track.java | 20 +- .../java/io/jenetics/jpx/TrackSegment.java | 16 +- .../main/java/io/jenetics/jpx/WayPoint.java | 16 +- .../main/java/io/jenetics/jpx/XMLReader.java | 34 +- .../main/java/io/jenetics/jpx/XMLWriter.java | 4 +- .../main/java/io/jenetics/jpx/geom/Geoid.java | 8 +- jpx/src/main/java/module-info.java | 32 +- 20 files changed, 143 insertions(+), 1509 deletions(-) delete mode 100644 buildSrc/resources/javadoc/stylesheet.css delete mode 100644 buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java delete mode 100644 buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java delete mode 100644 buildSrc/src/main/java/io/jenetics/gradle/package-info.java diff --git a/build.gradle.kts b/build.gradle.kts index d5164cff..7b67afe7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -166,13 +166,12 @@ fun setupJavadoc(project: Project) { doclet.charSet = "UTF-8" doclet.linkSource(true) doclet.linksOffline( - "https://docs.oracle.com/en/java/javase/17/docs/api/", + "https://docs.oracle.com/en/java/javase/21/docs/api/", "${project.rootDir}/buildSrc/resources/javadoc/java.se" ) doclet.windowTitle = "JPX ${project.version}" doclet.docTitle = "

JPX ${project.version}

" doclet.bottom = "© ${Env.COPYRIGHT_YEAR} Franz Wilhelmstötter  (${Env.BUILD_DATE})" - doclet.stylesheetFile = project.file("${project.rootDir}/buildSrc/resources/javadoc/stylesheet.css") doclet.tags = listOf( "apiNote:a:API Note:", @@ -190,38 +189,6 @@ fun setupJavadoc(project: Project) { } } } - - val javadoc = project.tasks.findByName("javadoc") as Javadoc? - if (javadoc != null) { - project.tasks.register("colorizer") { - directory = javadoc.destinationDir!! - } - - project.tasks.register("java2html") { - doLast { - project.javaexec { - mainClass.set("de.java2html.Java2Html") - args = listOf( - "-srcdir", "src/main/java", - "-targetdir", "${javadoc.destinationDir}/src-html/${project.extra["moduleName"]}" - ) - classpath = files("${project.rootDir}/buildSrc/lib/java2html.jar") - } - } - } - - javadoc.doLast { - val colorizer = project.tasks.findByName("colorizer") - colorizer?.actions?.forEach { - it.execute(colorizer) - } - - val java2html = project.tasks.findByName("java2html") - java2html?.actions?.forEach { - it.execute(java2html) - } - } - } } /** diff --git a/buildSrc/resources/javadoc/stylesheet.css b/buildSrc/resources/javadoc/stylesheet.css deleted file mode 100644 index d14736d0..00000000 --- a/buildSrc/resources/javadoc/stylesheet.css +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Javadoc style sheet - */ - -@import url('resources/fonts/dejavu.css'); - -/* - * Styles for individual HTML elements. - * - * These are styles that are specific to individual HTML elements. Changing them affects the style of a particular - * HTML element throughout the page. - */ - -div.code { - background-color:#F9F9F9; - margin-top:8px; - margin-bottom:8px; - margin-left:8px; - margin-right:25px; - border:1px solid #9EADC0; -} - -code[lang="java"] { - white-space:pre; - margin-top:5px; - font-family:'DejaVu Sans Mono', monospace; - font-size:1.0em; -} - -body { - background-color:#F5F5F5; - color:#353833; - font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; - font-size:14px; - margin:0; - padding:0; - height:100%; - width:100%; -} -iframe { - margin:0; - padding:0; - height:100%; - width:100%; - overflow-y:scroll; - border:none; -} -a:link, a:visited { - text-decoration:none; - color:#4A6782; -} -a[href]:hover, a[href]:focus { - text-decoration:none; - color:#bb7a2a; -} -a[name] { - color:#353833; -} -pre { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; -} -h1 { - font-size:20px; -} -h2 { - font-size:18px; -} -h3 { - font-size:16px; -} -h4 { - font-size:15px; -} -h5 { - font-size:14px; -} -h6 { - font-size:13px; -} -ul { - list-style-type:disc; -} -code, tt { - font-family:'DejaVu Sans Mono', monospace; -} -:not(h1, h2, h3, h4, h5, h6) > code, -:not(h1, h2, h3, h4, h5, h6) > tt { - font-size:14px; - padding-top:4px; - margin-top:8px; - line-height:1.4em; -} -dt code { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - padding-top:4px; -} -.summary-table dt code { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - vertical-align:top; - padding-top:4px; -} -sup { - font-size:8px; -} -button { - font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; - font-size: 14px; -} -/* - * Styles for HTML generated by javadoc. - * - * These are style classes that are used by the standard doclet to generate HTML documentation. - */ - -/* - * Styles for document title and copyright. - */ -.clear { - clear:both; - height:0; - overflow:hidden; -} -.about-language { - float:right; - padding:0 21px 8px 8px; - font-size:11px; - margin-top:-9px; - height:2.9em; -} -.legal-copy { - margin-left:.5em; -} -.tab { - background-color:#0066FF; - color:#ffffff; - padding:8px; - width:5em; - font-weight:bold; -} -/* - * Styles for navigation bar. - */ -@media screen { - .flex-box { - position:fixed; - display:flex; - flex-direction:column; - height: 100%; - width: 100%; - } - .flex-header { - flex: 0 0 auto; - } - .flex-content { - flex: 1 1 auto; - overflow-y: auto; - } -} -.top-nav { - background-color:#4D7A97; - color:#FFFFFF; - float:left; - padding:0; - width:100%; - clear:right; - min-height:2.8em; - padding-top:10px; - overflow:hidden; - font-size:12px; -} -.sub-nav { - background-color:#dee3e9; - float:left; - width:100%; - overflow:hidden; - font-size:12px; -} -.sub-nav div { - clear:left; - float:left; - padding:0 0 5px 6px; - text-transform:uppercase; -} -.sub-nav .nav-list { - padding-top:5px; -} -ul.nav-list { - display:block; - margin:0 25px 0 0; - padding:0; -} -ul.sub-nav-list { - float:left; - margin:0 25px 0 0; - padding:0; -} -ul.nav-list li { - list-style:none; - float:left; - padding: 5px 6px; - text-transform:uppercase; -} -.sub-nav .nav-list-search { - float:right; - margin:0 0 0 0; - padding:5px 6px; - clear:none; -} -.nav-list-search label { - position:relative; - right:-16px; -} -ul.sub-nav-list li { - list-style:none; - float:left; - padding-top:10px; -} -.top-nav a:link, .top-nav a:active, .top-nav a:visited { - color:#FFFFFF; - text-decoration:none; - text-transform:uppercase; -} -.top-nav a:hover { - text-decoration:none; - color:#bb7a2a; - text-transform:uppercase; -} -.nav-bar-cell1-rev { - background-color:#F8981D; - color:#253441; - margin: auto 5px; -} -.skip-nav { - position:absolute; - top:auto; - left:-9999px; - overflow:hidden; -} -/* - * Hide navigation links and search box in print layout - */ -@media print { - ul.nav-list, div.sub-nav { - display:none; - } -} -/* - * Styles for page header and footer. - */ -.title { - color:#2c4557; - margin:10px 0; -} -.sub-title { - margin:5px 0 0 0; -} -.header ul { - margin:0 0 15px 0; - padding:0; -} -.header ul li, .footer ul li { - list-style:none; - font-size:13px; -} -/* - * Styles for headings. - */ -body.class-declaration-page .summary h2, -body.class-declaration-page .details h2, -body.class-use-page h2, -body.module-declaration-page .block-list h2 { - font-style: italic; - padding:0; - margin:15px 0; -} -body.class-declaration-page .summary h3, -body.class-declaration-page .details h3, -body.class-declaration-page .summary .inherited-list h2 { - background-color:#dee3e9; - border:1px solid #d0d9e0; - margin:0 0 6px -8px; - padding:7px 5px; -} -/* - * Styles for page layout containers. - */ -main { - clear:both; - padding:10px 20px; - position:relative; -} -dl.notes > dt { - font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; - font-size:12px; - font-weight:bold; - margin:10px 0 0 0; - color:#4E4E4E; -} -dl.notes > dd { - margin:5px 10px 10px 0; - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; -} -dl.name-value > dt { - margin-left:1px; - font-size:1.1em; - display:inline; - font-weight:bold; -} -dl.name-value > dd { - margin:0 0 0 1px; - font-size:1.1em; - display:inline; -} -/* - * Styles for lists. - */ -li.circle { - list-style:circle; -} -ul.horizontal li { - display:inline; - font-size:0.9em; -} -div.inheritance { - margin:0; - padding:0; -} -div.inheritance div.inheritance { - margin-left:2em; -} -ul.block-list, -ul.details-list, -ul.member-list, -ul.summary-list { - margin:10px 0 10px 0; - padding:0; -} -ul.block-list > li, -ul.details-list > li, -ul.member-list > li, -ul.summary-list > li { - list-style:none; - margin-bottom:15px; - line-height:1.4; -} -.summary-table dl, .summary-table dl dt, .summary-table dl dd { - margin-top:0; - margin-bottom:1px; -} -ul.see-list, ul.see-list-long { - padding-left: 0; - list-style: none; -} -ul.see-list li { - display: inline; -} -ul.see-list li:not(:last-child):after, -ul.see-list-long li:not(:last-child):after { - content: ", "; - white-space: pre-wrap; -} -/* - * Styles for tables. - */ -.summary-table, .details-table { - width:100%; - border-spacing:0; - border-left:1px solid #EEE; - border-right:1px solid #EEE; - border-bottom:1px solid #EEE; - padding:0; -} -.caption { - position:relative; - text-align:left; - background-repeat:no-repeat; - color:#253441; - font-weight:bold; - clear:none; - overflow:hidden; - padding:0; - padding-top:10px; - padding-left:1px; - margin:0; - white-space:pre; -} -.caption a:link, .caption a:visited { - color:#1f389c; -} -.caption a:hover, -.caption a:active { - color:#FFFFFF; -} -.caption span { - white-space:nowrap; - padding-top:5px; - padding-left:12px; - padding-right:12px; - padding-bottom:7px; - display:inline-block; - float:left; - background-color:#F8981D; - border: none; - height:16px; -} -div.table-tabs { - padding:10px 0 0 1px; - margin:0; -} -div.table-tabs > button { - border: none; - cursor: pointer; - padding: 5px 12px 7px 12px; - font-weight: bold; - margin-right: 3px; -} -div.table-tabs > button.active-table-tab { - background: #F8981D; - color: #253441; -} -div.table-tabs > button.table-tab { - background: #4D7A97; - color: #FFFFFF; -} -.two-column-summary { - display: grid; - grid-template-columns: minmax(15%, max-content) minmax(15%, auto); -} -.three-column-summary { - display: grid; - grid-template-columns: minmax(10%, max-content) minmax(15%, max-content) minmax(15%, auto); -} -.four-column-summary { - display: grid; - grid-template-columns: minmax(10%, max-content) minmax(10%, max-content) minmax(10%, max-content) minmax(10%, auto); -} -@media screen and (max-width: 600px) { - .two-column-summary { - display: grid; - grid-template-columns: 1fr; - } -} -@media screen and (max-width: 800px) { - .three-column-summary { - display: grid; - grid-template-columns: minmax(10%, max-content) minmax(25%, auto); - } - .three-column-summary .col-last { - grid-column-end: span 2; - } -} -@media screen and (max-width: 1000px) { - .four-column-summary { - display: grid; - grid-template-columns: minmax(15%, max-content) minmax(15%, auto); - } -} -.summary-table > div, .details-table > div { - text-align:left; - padding: 8px 3px 3px 7px; -} -.col-first, .col-second, .col-last, .col-constructor-name, .col-summary-item-name { - vertical-align:top; - padding-right:0; - padding-top:8px; - padding-bottom:3px; -} -.table-header { - background:#dee3e9; - font-weight: bold; -} -.col-first, .col-first { - font-size:13px; -} -.col-second, .col-second, .col-last, .col-constructor-name, .col-summary-item-name, .col-last { - font-size:13px; -} -.col-first, .col-second, .col-constructor-name { - vertical-align:top; - overflow: auto; -} -.col-last { - white-space:normal; -} -.col-first a:link, .col-first a:visited, -.col-second a:link, .col-second a:visited, -.col-first a:link, .col-first a:visited, -.col-second a:link, .col-second a:visited, -.col-constructor-name a:link, .col-constructor-name a:visited, -.col-summary-item-name a:link, .col-summary-item-name a:visited, -.constant-values-container a:link, .constant-values-container a:visited, -.all-classes-container a:link, .all-classes-container a:visited, -.all-packages-container a:link, .all-packages-container a:visited { - font-weight:bold; -} -.table-sub-heading-color { - background-color:#EEEEFF; -} -.even-row-color, .even-row-color .table-header { - background-color:#FFFFFF; -} -.odd-row-color, .odd-row-color .table-header { - background-color:#EEEEEF; -} -/* - * Styles for contents. - */ -.deprecated-content { - margin:0; - padding:10px 0; -} -div.block { - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; -} -.col-last div { - padding-top:0; -} -.col-last a { - padding-bottom:3px; -} -.module-signature, -.package-signature, -.type-signature, -.member-signature { - font-family:'DejaVu Sans Mono', monospace; - font-size:14px; - margin:14px 0; - white-space: pre-wrap; -} -.module-signature, -.package-signature, -.type-signature { - margin-top: 0; -} -.member-signature .type-parameters-long, -.member-signature .parameters, -.member-signature .exceptions { - display: inline-block; - vertical-align: top; - white-space: pre; -} -.member-signature .type-parameters { - white-space: normal; -} -/* - * Styles for formatting effect. - */ -.source-line-no { - color:green; - padding:0 30px 0 0; -} -h1.hidden { - visibility:hidden; - overflow:hidden; - font-size:10px; -} -.block { - display:block; - margin:0 10px 5px 0; - color:#474747; -} -.deprecated-label, .descfrm-type-label, .implementation-label, .member-name-label, .member-name-link, -.module-label-in-package, .module-label-in-type, .override-specify-label, .package-label-in-type, -.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label { - font-weight:bold; -} -.deprecation-comment, .help-footnote, .preview-comment { - font-style:italic; -} -.deprecation-block { - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; - border-style:solid; - border-width:thin; - border-radius:10px; - padding:10px; - margin-bottom:10px; - margin-right:10px; - display:inline-block; -} -.preview-block { - font-size:14px; - font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; - border-style:solid; - border-width:thin; - border-radius:10px; - padding:10px; - margin-bottom:10px; - margin-right:10px; - display:inline-block; -} -div.block div.deprecation-comment { - font-style:normal; -} -/* - * Styles specific to HTML5 elements. - */ -main, nav, header, footer, section { - display:block; -} -/* - * Styles for javadoc search. - */ -.ui-autocomplete-category { - font-weight:bold; - font-size:15px; - padding:7px 0 7px 3px; - background-color:#4D7A97; - color:#FFFFFF; -} -.result-item { - font-size:13px; -} -.ui-autocomplete { - max-height:85%; - max-width:65%; - overflow-y:scroll; - overflow-x:scroll; - white-space:nowrap; - box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); -} -ul.ui-autocomplete { - position:fixed; - z-index:999999; -} -ul.ui-autocomplete li { - float:left; - clear:both; - width:100%; -} -.result-highlight { - font-weight:bold; -} -#search-input { - background-image:url('resources/glass.png'); - background-size:13px; - background-repeat:no-repeat; - background-position:2px 3px; - padding-left:20px; - position:relative; - right:-18px; - width:400px; -} -#reset-button { - background-color: rgb(255,255,255); - background-image:url('resources/x.png'); - background-position:center; - background-repeat:no-repeat; - background-size:12px; - border:0 none; - width:16px; - height:16px; - position:relative; - left:-4px; - top:-4px; - font-size:0px; -} -.watermark { - color:#545454; -} -.search-tag-desc-result { - font-style:italic; - font-size:11px; -} -.search-tag-holder-result { - font-style:italic; - font-size:12px; -} -.search-tag-result:target { - background-color:yellow; -} -.module-graph span { - display:none; - position:absolute; -} -.module-graph:hover span { - display:block; - margin: -100px 0 0 100px; - z-index: 1; -} -.inherited-list { - margin: 10px 0 10px 0; -} -section.class-description { - line-height: 1.4; -} -.summary section[class$="-summary"], .details section[class$="-details"], -.class-uses .detail, .serialized-class-details { - padding: 0px 20px 5px 10px; - border: 1px solid #ededed; - background-color: #f8f8f8; -} -.inherited-list, section[class$="-details"] .detail { - padding:0 0 5px 8px; - background-color:#ffffff; - border:none; -} -.vertical-separator { - padding: 0 5px; -} -ul.help-section-list { - margin: 0; -} -ul.help-subtoc > li { - display: inline-block; - padding-right: 5px; - font-size: smaller; -} -ul.help-subtoc > li::before { - content: "\2022" ; - padding-right:2px; -} -span.help-note { - font-style: italic; -} -/* - * Indicator icon for external links. - */ -main a[href*="://"]::after { - content:""; - display:inline-block; - background-image:url('data:image/svg+xml; utf8, \ - \ - \ - '); - background-size:100% 100%; - width:7px; - height:7px; - margin-left:2px; - margin-bottom:4px; -} -main a[href*="://"]:hover::after, -main a[href*="://"]:focus::after { - background-image:url('data:image/svg+xml; utf8, \ - \ - \ - '); -} - -/* - * Styles for user-provided tables. - * - * borderless: - * No borders, vertical margins, styled caption. - * This style is provided for use with existing doc comments. - * In general, borderless tables should not be used for layout purposes. - * - * plain: - * Plain borders around table and cells, vertical margins, styled caption. - * Best for small tables or for complex tables for tables with cells that span - * rows and columns, when the "striped" style does not work well. - * - * striped: - * Borders around the table and vertical borders between cells, striped rows, - * vertical margins, styled caption. - * Best for tables that have a header row, and a body containing a series of simple rows. - */ - -table.borderless, -table.plain, -table.striped { - margin-top: 10px; - margin-bottom: 10px; -} -table.borderless > caption, -table.plain > caption, -table.striped > caption { - font-weight: bold; - font-size: smaller; -} -table.borderless th, table.borderless td, -table.plain th, table.plain td, -table.striped th, table.striped td { - padding: 2px 5px; -} -table.borderless, -table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th, -table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td { - border: none; -} -table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr { - background-color: transparent; -} -table.plain { - border-collapse: collapse; - border: 1px solid black; -} -table.plain > thead > tr, table.plain > tbody tr, table.plain > tr { - background-color: transparent; -} -table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th, -table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td { - border: 1px solid black; -} -table.striped { - border-collapse: collapse; - border: 1px solid black; -} -table.striped > thead { - background-color: #E3E3E3; -} -table.striped > thead > tr > th, table.striped > thead > tr > td { - border: 1px solid black; -} -table.striped > tbody > tr:nth-child(even) { - background-color: #EEE -} -table.striped > tbody > tr:nth-child(odd) { - background-color: #FFF -} -table.striped > tbody > tr > th, table.striped > tbody > tr > td { - border-left: 1px solid black; - border-right: 1px solid black; -} -table.striped > tbody > tr > th { - font-weight: normal; -} -/** - * Tweak font sizes and paddings for small screens. - */ -@media screen and (max-width: 1050px) { - #search-input { - width: 300px; - } -} -@media screen and (max-width: 800px) { - #search-input { - width: 200px; - } - .top-nav, - .bottom-nav { - font-size: 11px; - padding-top: 6px; - } - .sub-nav { - font-size: 11px; - } - .about-language { - padding-right: 16px; - } - ul.nav-list li, - .sub-nav .nav-list-search { - padding: 6px; - } - ul.sub-nav-list li { - padding-top: 5px; - } - main { - padding: 10px; - } - .summary section[class$="-summary"], .details section[class$="-details"], - .class-uses .detail, .serialized-class-details { - padding: 0 8px 5px 8px; - } - body { - -webkit-text-size-adjust: none; - } -} -@media screen and (max-width: 500px) { - #search-input { - width: 150px; - } - .top-nav, - .bottom-nav { - font-size: 10px; - } - .sub-nav { - font-size: 10px; - } - .about-language { - font-size: 10px; - padding-right: 12px; - } -} diff --git a/buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java b/buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java deleted file mode 100644 index c360c86b..00000000 --- a/buildSrc/src/main/java/io/jenetics/gradle/Colorizer.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Java GPX Library (@__identifier__@). - * Copyright (c) @__year__@ Franz Wilhelmstötter - * - * 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. - * - * Author: - * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) - */ -package io.jenetics.gradle; - -import static java.lang.String.format; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Objects.requireNonNull; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.Charset; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Set; - -/** - * @author Franz Wilhelmstötter - * @since 1.0 - * @version 6.1 - */ -public final class Colorizer extends SimpleFileVisitor { - - private static final Charset CHARSET = UTF_8; - - // Original start tag:
{@code
-	private static final String START_TAG = "
";
-
-	// Original end tag: }
- private static final String END_TAG = "
"; - - private File _baseDir; - - private int _processed = 0; - private int _modified = 0; - - public Colorizer(final File baseDir) { - _baseDir = requireNonNull(baseDir, "Base dir must not be null."); - } - - public Colorizer() { - this(new File(".")); - } - - public void setBaseDir(final File baseDir) { - _baseDir = requireNonNull(baseDir, "Base dir must not be null."); - } - - public File getBaseDir() { - return _baseDir; - } - - public int getProcessed() { - return _processed; - } - - public int getModified() { - return _modified; - } - - public void colorize() throws IOException { - Files.walkFileTree(_baseDir.toPath(), this); - } - - @Override - public FileVisitResult visitFile( - final Path file, - final BasicFileAttributes attrs - ) { - if (file.toString().endsWith(".html")) { - try { - colorize(file); - } catch (IOException e) { - System.out.println("Error while processing file: " + file); - return FileVisitResult.TERMINATE; - } - } - - return FileVisitResult.CONTINUE; - } - - private void colorize(final Path file) throws IOException { - ++_processed; - - try (FileInputStream fis = new FileInputStream(file.toFile()); - InputStreamReader isr = new InputStreamReader(fis, CHARSET); - BufferedReader in = new BufferedReader(isr)) - { - final StringBuilder out = new StringBuilder(10000); - State state = State.DATA; - boolean modified = false; - - for (int ch = in.read(); ch != -1; ch = in.read()) { - out.append((char)ch); - - if (state == State.CODE_TAG) { - modified = true; - } - - state = state.apply((char)ch, out); - } - - if (modified) { - ++_modified; - try (FileOutputStream fout = new FileOutputStream(file.toFile()); - OutputStreamWriter writer = new OutputStreamWriter(fout, CHARSET)) - { - writer.write(out.toString()); - } - } - } - } - - /** - * Represents the current 'Colorizer' state. - * - * @author Franz Wilhelmstötter - * @since 1.0 - * @version 1.4 - */ - private enum State { - - DATA { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '>') && - (out.length() >= START_TAG.length()) && - out.substring(out.length() - START_TAG.length()) - .equalsIgnoreCase(START_TAG)) - { - out.setLength(out.length() - START_TAG.length()); - out.append("
"); - state = SKIP_NEWLINE; - } - - return state; - } - }, - - SKIP_NEWLINE { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if (ch == '\n') { - out.setLength(out.length() - 1); - state = CODE_TAG; - } - return state; - } - }, - - CODE_TAG { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if (Character.isJavaIdentifierPart(ch)) { - state = IDENTIFIER; - state._start = out.length() - 1; - } else if (ch == '"') { - state = STRING_LITERAL; - out.insert( - out.length() - 1, - "" - ); - } else if ((ch == '/') && (out.charAt(out.length() - 2) == '/')) { - state = COMMENT; - out.insert( - out.length() - 2, - "" - ); - } else if ((ch == '@') && - (out.charAt(out.length() - 2) == '\\') && - (out.charAt(out.length() - 3) != '\\')) - { - state = ANNOTATION; - out.deleteCharAt(out.length() - 2); - out.insert( - out.length() - 1, - "" - ); - } - - return state; - } - }, - - IDENTIFIER { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '>') && - out.substring(out.length() - END_TAG.length()) - .equalsIgnoreCase(END_TAG)) - { - int index = out.lastIndexOf("\n"); - out.setLength(index); - out.append("
"); - state = DATA; - } else if (!Character.isJavaIdentifierPart(ch)) { - final String name = out.substring(_start, out.length() - 1); - if (IDENTIFIERS.contains(name)) { - out.insert(_start + name.length(), ""); - out.insert( - _start, - "" - ); - } - state = CODE_TAG; - } - - return state; - } - }, - - ANNOTATION { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if (!Character.isJavaIdentifierPart(ch)) { - out.insert(out.length() - 1, ""); - state = CODE_TAG; - } - return state; - } - }, - - STRING_LITERAL { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '"') && (out.charAt(out.length() - 2) != '\\')) { - out.append(""); - state = CODE_TAG; - } - return state; - } - }, - - COMMENT { - @Override - public State apply(final char ch, final StringBuilder out) { - State state = this; - if ((ch == '\n') || (ch == '\r')) { - out.insert(out.length() - 1, ""); - state = CODE_TAG; - } - return state; - } - }; - - int _start = -1; - - public abstract State apply(final char read, final StringBuilder doc); - - private static final String ANNOTATION_COLOR = "#808080"; - private static final String KEYWORD_COLOR = "#7F0055"; - private static final String COMMENT_COLOR = "#3F7F5F"; - private static final String STRING_COLOR = "#0000FF"; - - private static final Set IDENTIFIERS = Set.of( - "abstract", - "assert", - "boolean", - "break", - "byte", - "case", - "catch", - "char", - "class", - "const", - "continue", - "default", - "do", - "double", - "else", - "enum", - "extends", - "final", - "finally", - "float", - "for", - "goto", - "if", - "implements", - "import", - "instanceof", - "int", - "interface", - "long", - "native", - "null", - "new", - "package", - "private", - "protected", - "public", - "return", - "short", - "static", - "strictfp", - "super", - "switch", - "synchronized", - "this", - "throw", - "throws", - "transient", - "try", - "void", - "volatile", - "while" - ); - } - - - public static void main(final String[] args) { - final File dir = new File(args[0]); - if (!dir.isDirectory()) { - System.err.println(args[0] + " is not a directory."); - System.exit(1); - } - - try { - final Colorizer colorizer = new Colorizer(dir); - colorizer.colorize(); - - System.out.println(format( - "Colorizer processed %d files and modified %d.", - colorizer.getProcessed(), - colorizer.getModified() - )); - } catch (IOException e) { - System.err.println("Error while processing files: " + e); - System.exit(1); - } - } - -} diff --git a/buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java b/buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java deleted file mode 100644 index 1b0c8e45..00000000 --- a/buildSrc/src/main/java/io/jenetics/gradle/ColorizerTask.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Java GPX Library (@__identifier__@). - * Copyright (c) @__year__@ Franz Wilhelmstötter - * - * 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. - * - * Author: - * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) - */ -package io.jenetics.gradle; - -import java.io.File; -import java.io.IOException; - -import org.gradle.api.DefaultTask; -import org.gradle.api.tasks.InputFile; -import org.gradle.api.tasks.TaskAction; -import org.gradle.api.tasks.TaskExecutionException; - -/** - * @author Franz Wilhelmstötter - * @since 1.4 - * @version 6.1 - */ -public class ColorizerTask extends DefaultTask { - - private File _directory; - - @InputFile - public File getDirectory() { - return _directory; - } - - public void setDirectory(final File directory) { - _directory = directory; - } - - @TaskAction - public void colorize() { - try { - final Colorizer colorizer = new Colorizer(_directory); - colorizer.colorize(); - - getLogger().lifecycle( - "Colorizer processed {} files and modified {}.", - colorizer.getProcessed(), colorizer.getModified() - ); - } catch (final IOException e) { - throw new TaskExecutionException(this, e); - } - } - -} diff --git a/buildSrc/src/main/java/io/jenetics/gradle/package-info.java b/buildSrc/src/main/java/io/jenetics/gradle/package-info.java deleted file mode 100644 index 989fa875..00000000 --- a/buildSrc/src/main/java/io/jenetics/gradle/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Java GPX Library (@__identifier__@). - * Copyright (c) @__year__@ Franz Wilhelmstötter - * - * 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. - * - * Author: - * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) - */ - -/** - * @author Franz Wilhelmstötter - * @since 1.4 - * @version 1.4 - */ -package io.jenetics.gradle; diff --git a/jpx/src/main/java/io/jenetics/jpx/Bounds.java b/jpx/src/main/java/io/jenetics/jpx/Bounds.java index 475239ee..73844eba 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Bounds.java +++ b/jpx/src/main/java/io/jenetics/jpx/Bounds.java @@ -141,12 +141,12 @@ public String toString() { * stream. The following example shows how to calculate the bounds of all * track-points of a given GPX object. * - *
{@code
+	 * {@snippet lang="java":
 	 * final Bounds bounds = gpx.tracks()
 	 *     .flatMap(Track::segments)
 	 *     .flatMap(TrackSegment::points)
 	 *     .collect(Bounds.toBounds());
-	 * }
+ * } * * If the collecting way-point stream is empty, the collected {@code Bounds} * object is {@code null}. diff --git a/jpx/src/main/java/io/jenetics/jpx/Email.java b/jpx/src/main/java/io/jenetics/jpx/Email.java index 6c24b799..9bf09419 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Email.java +++ b/jpx/src/main/java/io/jenetics/jpx/Email.java @@ -128,7 +128,7 @@ public String toString() { * @param id id half of email address (billgates2004) * @param domain domain half of email address (hotmail.com) * @return a new {@code Email} object with the given values - * @throws NullPointerException if one of the argument is {@code null} + * @throws NullPointerException if one of the arguments is {@code null} */ public static Email of(final String id, final String domain) { return new Email(id, domain); @@ -139,7 +139,7 @@ public static Email of(final String id, final String domain) { * * @param address the email address string * @return a new {@code Email} object with {@code address} - * @throws NullPointerException if one of the argument is {@code null} + * @throws NullPointerException if one of the arguments is {@code null} * @throws IllegalArgumentException if the given {@code address} is invalid */ public static Email of(final String address) { @@ -150,7 +150,7 @@ public static Email of(final String address) { } final int index = address.indexOf('@'); - if (index == -1 || index == 0 || index == address.length()) { + if (index == -1 || index == 0 || index == address.length() - 1) { throw new IllegalArgumentException(format( "Invalid email: '%s'.", address )); diff --git a/jpx/src/main/java/io/jenetics/jpx/Filters.java b/jpx/src/main/java/io/jenetics/jpx/Filters.java index 41ba26fe..bdb83835 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Filters.java +++ b/jpx/src/main/java/io/jenetics/jpx/Filters.java @@ -43,7 +43,7 @@ private Filters() { /** * Merges the given segments into one segment containing all way-points. The * order of the way-points is preserved. - *
{@code
+	 * {@snippet lang="java":
 	 * final GPX merged = gpx.toBuilder()
 	 *     .trackFilter()
 	 *         .map(track -> track.toBuilder()
@@ -52,7 +52,7 @@ private Filters() {
 	 *             .build())
 	 *         .build()
 	 *     .build();
-	 * }
+ * } * * @param segments the segment list to merge * @return a list with one segment, containing all way-points of the original @@ -72,14 +72,14 @@ public static List mergeSegments( /** * Merges the given tracks into one track containing all segments. The order * of the segments is preserved. - *
{@code
+	 * {@snippet lang="java":
 	 * final GPX merged = gpx.toBuilder()
 	 *     .trackFilter()
 	 *         .listMap(Filters::mergeTracks)
 	 *         .filter(Track::nonEmpty)
 	 *         .build())
 	 *     .build();
-	 * }
+ * } * * @param tracks the track list to merge * @return a list with one track, containing all segments @@ -103,13 +103,13 @@ public static List mergeTracks(final List tracks) { * Merges all way-points of all segments of the given track list into one * track with one segment, containing all way-points. The order of the * way-points is preserved. - *
{@code
+	 * {@snippet lang="java":
 	 * final GPX merged = gpx.toBuilder()
 	 *     .trackFilter()
 	 *         .listMap(Filters::fullyMergeTracks)
 	 *         .build())
 	 *     .build();
-	 * }
+ * } * * * @param tracks the track list to merge @@ -135,10 +135,10 @@ public static List fullyMergeTracks(final List tracks) { * Return a new {@code GPX} object with all empty elements (tracks, * track-segments, routes and metadata) removed. This method can be used * to clean up the GPX object before writing it to file. - *
{@code
+	 * {@snippet lang="java":
 	 * final GPX gpx = ...;
 	 * final GPX.write(Filters.nonEmptyGPX(gpx), "tracks.gpx", "    ");
-	 * }
+ * } * * @param gpx the GPX object to clean up * @return a new {@code GPX} object with all empty elements removed diff --git a/jpx/src/main/java/io/jenetics/jpx/GPX.java b/jpx/src/main/java/io/jenetics/jpx/GPX.java index 24cfc537..080d9373 100644 --- a/jpx/src/main/java/io/jenetics/jpx/GPX.java +++ b/jpx/src/main/java/io/jenetics/jpx/GPX.java @@ -77,7 +77,7 @@ * Examples: *

* Creating a GPX object with one track-segment and 3 track-points - *

{@code
+ * {@snippet lang="java":
  * final GPX gpx = GPX.builder()
  *     .addTrack(track -> track
  *         .addSegment(segment -> segment
@@ -85,16 +85,16 @@
  *             .addPoint(p -> p.lat(48.20112).lon(16.31639).ele(278))
  *             .addPoint(p -> p.lat(48.20126).lon(16.31601).ele(274))))
  *     .build();
- * }
+ * } * * Writing a GPX file - *
{@code
+ * {@snippet lang="java":
  * final var indent = new GPX.Writer.Indent("    ");
  * GPX.Writer.of(indent).write(gpx, Path.of("points.gpx"));
- * }
+ * } * * This will produce the following output. - *
{@code
+ * {@snippet lang="java":
  * 
  *     
  *         
@@ -110,20 +110,20 @@
  *         
  *     
  * 
- * }
+ * } * * Reading a GPX file - *
{@code
+ * {@snippet lang="java":
  * final GPX gpx = GPX.read("points.xml");
- * }
+ * } * * Reading erroneous GPX files - *
{@code
+ * {@snippet lang="java":
  * final GPX gpx = GPX.Reader.of(GPX.Reader.Mode.LENIENT).read("track.xml");
- * }
+ * } * * This allows to read otherwise invalid GPX files, like - *
{@code
+ * {@snippet lang="java":
  * 
  * 
  *   
@@ -155,10 +155,10 @@
  *     
  *   
  * 
- * }
+ * } * * which is read as (if you write it again) - *
{@code
+ * {@snippet lang="java":
  * 
  * 
  *     
@@ -190,10 +190,10 @@
  *         
  *     
  * 
- * }
+ * } * * Converting a GPX object to an XML {@link Document} - *
{@code
+ * {@snippet lang="java":
  * final GPX gpx = ...;
  *
  * final Document doc = XMLProvider.provider()
@@ -203,7 +203,7 @@
  *
  * // The GPX data are written to the empty `doc` object.
  * GPX.Writer.DEFAULT.write(gpx, new DOMResult(doc));
- * }
+ * } * * @author Franz Wilhelmstötter * @version 2.0 @@ -416,11 +416,11 @@ public Stream tracks() { /** * Return the (cloned) extensions document. The root element of the returned * document has the name {@code extensions}. - *
{@code
+	 * {@snippet lang="java":
 	 * 
 	 *     ...
 	 * 
-	 * }
+ * } * * @since 1.5 * @@ -484,7 +484,7 @@ public boolean equals(final Object obj) { * Builder class for creating immutable {@code GPX} objects. *

* Creating a GPX object with one track-segment and 3 track-points: - *

{@code
+	 * {@snippet lang="java":
 	 * final GPX gpx = GPX.builder()
 	 *     .addTrack(track -> track
 	 *         .addSegment(segment -> segment
@@ -492,7 +492,7 @@ public boolean equals(final Object obj) {
 	 *             .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(161))
 	 *             .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(162))))
 	 *     .build();
-	 * }
+ * } */ public static final class Builder { private String _creator; @@ -570,12 +570,12 @@ public Builder metadata(final Metadata metadata) { /** * Allows setting partial metadata without messing up with the * {@link Metadata.Builder} class. - *
{@code
+		 * {@snippet lang="java":
 		 * final GPX gpx = GPX.builder()
 		 *     .metadata(md -> md.author("Franz Wilhelmstötter"))
 		 *     .addTrack(...)
 		 *     .build();
-		 * }
+ * } * * @param metadata the metadata consumer * @return {@code this} {@code Builder} for method chaining @@ -632,11 +632,11 @@ public Builder addWayPoint(final WayPoint wayPoint) { /** * Add a way-point to the {@code GPX} object using a * {@link WayPoint.Builder}. - *
{@code
+		 * {@snippet lang="java":
 		 * final GPX gpx = GPX.builder()
 		 *     .addWayPoint(wp -> wp.lat(23.6).lon(13.5).ele(50))
 		 *     .build();
-		 * }
+ * } * * @param wayPoint the way-point to add, configured by the way-point * builder @@ -687,13 +687,13 @@ public Builder addRoute(final Route route) { /** * Add a route the {@code GPX} object. - *
{@code
+		 * {@snippet lang="java":
 		 * final GPX gpx = GPX.builder()
 		 *     .addRoute(route -> route
 		 *         .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(160))
 		 *         .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(161)))
 		 *     .build();
-		 * }
+ * } * * @param route the route to add, configured by the route builder * @return {@code this} {@code Builder} for method chaining @@ -743,7 +743,7 @@ public Builder addTrack(final Track track) { /** * Add a track the {@code GPX} object. - *
{@code
+		 * {@snippet lang="java":
 		 * final GPX gpx = GPX.builder()
 		 *     .addTrack(track -> track
 		 *         .addSegment(segment -> segment
@@ -751,7 +751,7 @@ public Builder addTrack(final Track track) {
 		 *             .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(161))
 		 *             .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(162))))
 		 *     .build();
-		 * }
+ * } * * @param track the track to add, configured by the track builder * @return {@code this} {@code Builder} for method chaining @@ -778,11 +778,11 @@ public List tracks() { /** * Sets the extensions object, which may be {@code null}. The root * element of the extensions document must be {@code extensions}. - *
{@code
+		 * {@snippet lang="java":
 		 * 
 		 *     ...
 		 * 
-		 * }
+ * } * * @since 1.5 * @@ -826,13 +826,13 @@ public GPX build() { /** * Return a new {@link WayPoint} filter. - *
{@code
+		 * {@snippet lang="java":
 		 * final GPX filtered = gpx.toBuilder()
 		 *     .wayPointFilter()
 		 *         .filter(wp -> wp.getTime().isPresent())
 		 *         .build())
 		 *     .build();
-		 * }
+ * } * * @since 1.1 * @@ -898,13 +898,13 @@ public Builder build() { /** * Return a new {@link Route} filter. - *
{@code
+		 * {@snippet lang="java":
 		 * final GPX filtered = gpx.toBuilder()
 		 *     .routeFilter()
 		 *         .filter(Route::nonEmpty)
 		 *         .build())
 		 *     .build();
-		 * }
+ * } * * @since 1.1 * @@ -973,7 +973,7 @@ public Builder build() { /** * Return a new {@link Track} filter. - *
{@code
+		 * {@snippet lang="java":
 		 * final GPX merged = gpx.toBuilder()
 		 *     .trackFilter()
 		 *         .map(track -> track.toBuilder()
@@ -982,7 +982,7 @@ public Builder build() {
 		 *             .build())
 		 *         .build()
 		 *     .build();
-		 * }
+ * } * * @since 1.1 * @@ -1459,7 +1459,7 @@ public int maximumFractionDigits() { *

* The following example shows how to create an XML-Document from a * given {@code GPX} object. - *

{@code
+		 * {@snippet lang="java":
 		 * final GPX gpx = ...;
 		 *
 		 * final Document doc = XMLProvider.provider()
@@ -1469,7 +1469,7 @@ public int maximumFractionDigits() {
 		 *
 		 * // The GPX data are written to the empty `doc` object.
 		 * GPX.Writer.DEFAULT.write(gpx, new DOMResult(doc));
-		 * }
+ * } * * @since 3.0 * @@ -1624,12 +1624,12 @@ byte[] toByteArray(final GPX gpx) { *

* The example below shows the lat and lon values with * maximal 5 fractional digits. - *

{@code
+		 * {@snippet lang="java":
 		 * 
 		 *     1.2
 		 *     
 		 * 
-		 * }
+ * } * * The following table should give you a feeling about the accuracy of a * given fraction digits count, at the equator. @@ -2058,9 +2058,9 @@ private static GPX toGPXv10(final Object[] v) { * Writes the given {@code gpx} object (in GPX XML format) to the given * {@code path}. * This method is a shortcut for - *
{@code
+	 * {@snippet lang="java":
 	 * GPX.Writer.DEFAULT.write(gpx, path);
-	 * }
+ * } * * @see Writer * @@ -2078,9 +2078,9 @@ public static void write(final GPX gpx, final Path path) throws IOException { /** * Read an GPX object from the given {@code input} stream. * This method is a shortcut for - *
{@code
+	 * {@snippet lang="java":
 	 * GPX.Reader.DEFAULT.read(path);
-	 * }
+ * } * * @see Reader * diff --git a/jpx/src/main/java/io/jenetics/jpx/Length.java b/jpx/src/main/java/io/jenetics/jpx/Length.java index 897986a2..5584cbe5 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Length.java +++ b/jpx/src/main/java/io/jenetics/jpx/Length.java @@ -112,9 +112,9 @@ public enum Unit { * length value of {@code this} length unit. The given example converts 3 * inches into yards. * - *
{@code
+		 * {@snippet lang="java":
 		 * final double yards = YARD.convert(3, INCH);
-		 * }
+ * } * * @param length the length value * @param sourceUnit the source length unit diff --git a/jpx/src/main/java/io/jenetics/jpx/Metadata.java b/jpx/src/main/java/io/jenetics/jpx/Metadata.java index 72ad242b..d8a3ae05 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Metadata.java +++ b/jpx/src/main/java/io/jenetics/jpx/Metadata.java @@ -45,12 +45,12 @@ * files allows others to search for and use your GPS data. *

* Creating a GPX object with one track-segment and 3 track-points: - *

{@code
+ * {@snippet lang="java":
  * final Metadata gpx = Metadata.builder()
  *     .author("Franz Wilhelmstötter")
  *     .addLink(Link.of("http://jenetics.io"))
  *     .build();
- * }
+ * } * * @author Franz Wilhelmstötter * @version 3.0 @@ -188,11 +188,11 @@ public Optional getBounds() { /** * Return the (cloned) extensions document. The root element of the returned * document has the name {@code extensions}. - *
{@code
+	 * {@snippet lang="java":
 	 * 
 	 *     ...
 	 * 
-	 * }
+ * } * * @since 1.5 * @@ -286,12 +286,12 @@ public boolean equals(final Object obj) { * Builder class for creating immutable {@code Metadata} objects. *

* Creating a GPX object with one track-segment and 3 track-points: - *

{@code
+	 * {@snippet lang="java":
 	 * final Metadata gpx = Metadata.builder()
 	 *     .author("Franz Wilhelmstötter")
 	 *     .addLink(Link.of("http://jenetics.io"))
 	 *     .build();
-	 * }
+ * } */ public static final class Builder { private String _name; @@ -555,11 +555,11 @@ public Optional bounds() { /** * Sets the extensions object, which may be {@code null}. The root * element of the extensions document must be {@code extensions}. - *
{@code
+		 * {@snippet lang="java":
 		 * 
 		 *     ...
 		 * 
-		 * }
+ * } * * @since 1.5 * diff --git a/jpx/src/main/java/io/jenetics/jpx/Route.java b/jpx/src/main/java/io/jenetics/jpx/Route.java index a83e5081..068a87f6 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Route.java +++ b/jpx/src/main/java/io/jenetics/jpx/Route.java @@ -53,7 +53,7 @@ * turn points leading to a destination. *

* Create a new route via the builder: - *

{@code
+ * {@snippet lang="java":
  * final Route route = Route.builder()
  *     .name("Route 1")
  *     .description("Fancy mountain-bike tour.")
@@ -61,7 +61,7 @@
  *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(161))
  *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(162))))
  *     .build();
- * }
+ * } * * @author Franz Wilhelmstötter * @version 1.5 @@ -203,11 +203,11 @@ public Stream points() { /** * Return the (cloned) extensions document. The root element of the returned * document has the name {@code extensions}. - *
{@code
+	 * {@snippet lang="java":
 	 * 
 	 *     ...
 	 * 
-	 * }
+ * } * * @since 1.5 * @@ -320,7 +320,7 @@ public static Builder builder() { /** * Builder class for building {@code Route} objects. - *
{@code
+	 * {@snippet lang="java":
 	 * final Route route = Route.builder()
 	 *     .name("Route 1")
 	 *     .description("Fancy mountain-bike tour.")
@@ -328,7 +328,7 @@ public static Builder builder() {
 	 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(161))
 	 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(162))))
 	 *     .build();
-	 * }
+ * } */ public static final class Builder implements Filter { @@ -544,11 +544,11 @@ public Optional type() { /** * Sets the extensions object, which may be {@code null}. The root * element of the extensions document must be {@code extensions}. - *
{@code
+		 * {@snippet lang="java":
 		 * 
 		 *     ...
 		 * 
-		 * }
+ * } * * @since 1.5 * diff --git a/jpx/src/main/java/io/jenetics/jpx/Speed.java b/jpx/src/main/java/io/jenetics/jpx/Speed.java index 999fea06..186102a6 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Speed.java +++ b/jpx/src/main/java/io/jenetics/jpx/Speed.java @@ -89,9 +89,9 @@ public enum Unit { * speed value of {@code this} speed unit. The given example converts 3 * knots into kilometers per hour. * - *
{@code
+		 * {@snippet lang="java":
 		 * final double kilometersPerHour = KILOMETERS_PER_HOUR.convert(3, KNOTS);
-		 * }
+ * } * * @param speed the speed value * @param sourceUnit the source speed unit diff --git a/jpx/src/main/java/io/jenetics/jpx/Track.java b/jpx/src/main/java/io/jenetics/jpx/Track.java index 57515541..2713ce9b 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Track.java +++ b/jpx/src/main/java/io/jenetics/jpx/Track.java @@ -52,7 +52,7 @@ * Represents a GPX track - an ordered list of points describing a path. *

* Creating a Track object with one track-segment and 3 track-points: - *

{@code
+ * {@snippet lang="java":
  * final Track track = Track.builder()
  *     .name("Track 1")
  *     .description("Mountain bike tour.")
@@ -65,7 +65,7 @@
  *         .addPoint(p -> p.lat(47.2081743).lon(16.3738189).ele(161))
  *         .addPoint(p -> p.lat(49.2081743).lon(16.3738189).ele(162))))
  *     .build();
- * }
+ * } * * @author Franz Wilhelmstötter * @version 1.5 @@ -192,11 +192,11 @@ public Optional getType() { /** * Return the (cloned) extensions document. The root element of the returned * document has the name {@code extensions}. - *
{@code
+	 * {@snippet lang="java":
 	 * 
 	 *     ...
 	 * 
-	 * }
+ * } * * @since 1.5 * @@ -317,7 +317,7 @@ public String toString() { * Builder class for creating immutable {@code Track} objects. *

* Creating a Track object with one track-segment and 3 track-points: - *

{@code
+	 * {@snippet lang="java":
 	 * final Track track = Track.builder()
 	 *     .name("Track 1")
 	 *     .description("Mountain bike tour.")
@@ -330,7 +330,7 @@ public String toString() {
 	 *         .addPoint(p -> p.lat(47.2081743).lon(16.3738189).ele(161))
 	 *         .addPoint(p -> p.lat(49.2081743).lon(16.3738189).ele(162))))
 	 *     .build();
-	 * }
+ * } */ public static final class Builder implements Filter { private String _name; @@ -536,11 +536,11 @@ public Optional type() { /** * Sets the extensions object, which may be {@code null}. The root * element of the extensions document must be {@code extensions}. - *
{@code
+		 * {@snippet lang="java":
 		 * 
 		 *     ...
 		 * 
-		 * }
+ * } * * @since 1.5 * @@ -592,7 +592,7 @@ public Builder addSegment(final TrackSegment segment) { /** * Add a track segment to the track, via the given builder. - *
{@code
+		 * {@snippet lang="java":
 		 * final Track track = Track.builder()
 		 *     .name("Track 1")
 		 *     .description("Mountain bike tour.")
@@ -605,7 +605,7 @@ public Builder addSegment(final TrackSegment segment) {
 		 *         .addPoint(p -> p.lat(47.2081743).lon(16.3738189).ele(161))
 		 *         .addPoint(p -> p.lat(49.2081743).lon(16.3738189).ele(162))))
 		 *     .build();
-		 * }
+ * } * * @param segment the track segment * @return {@code this} {@code Builder} for method chaining diff --git a/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java b/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java index 5138d5e7..ce12f479 100644 --- a/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java +++ b/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java @@ -101,11 +101,11 @@ public Iterator iterator() { /** * Return the (cloned) extensions document. The root element of the returned * document has the name {@code extensions}. - *
{@code
+	 * {@snippet lang="java":
 	 * 
 	 *     ...
 	 * 
-	 * }
+ * } * * @since 1.5 * @@ -178,13 +178,13 @@ public String toString() { * Builder class for creating immutable {@code TrackSegment} objects. *

* Creating a {@code TrackSegment} object with 3 track-points: - *

{@code
+	 * {@snippet lang="java":
 	 * final TrackSegment segment = TrackSegment.builder()
 	 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(160))
 	 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(161))
 	 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(162))))
 	 *     .build();
-	 * }
+ * } */ public static final class Builder implements Filter { private final List _points = new ArrayList<>(); @@ -223,13 +223,13 @@ public Builder addPoint(final WayPoint point) { * Add a way-point to the track-segment, via the given way-point builder. *

* Creating a {@code TrackSegment} object with 3 track-points: - *

{@code
+		 * {@snippet lang="java":
 		 * final TrackSegment segment = TrackSegment.builder()
 		 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(160))
 		 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(161))
 		 *     .addPoint(p -> p.lat(48.2081743).lon(16.3738189).ele(162))))
 		 *     .build();
-		 * }
+ * } * * @param point the segment way-point builder * @return {@code this} {@code Builder} for method chaining @@ -255,11 +255,11 @@ public List points() { /** * Sets the extensions object, which may be {@code null}. The root * element of the extensions document must be {@code extensions}. - *
{@code
+		 * {@snippet lang="java":
 		 * 
 		 *     ...
 		 * 
-		 * }
+ * } * * @since 1.5 * diff --git a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java index 5947fffa..97a2de88 100644 --- a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java +++ b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java @@ -53,11 +53,11 @@ * feature on a map. *

* Creating a {@code WayPoint}: - *

{@code
+ * {@snippet lang="java":
  * final WayPoint point = WayPoint.builder()
  *     .lat(48.2081743).lon(16.3738189).ele(160)
  *     .build();
- * }
+ * } * * @author Franz Wilhelmstötter * @version 3.0 @@ -385,11 +385,11 @@ public Optional getCourse() { /** * Return the (cloned) extensions document. The root element of the returned * document has the name {@code extensions}. - *
{@code
+	 * {@snippet lang="java":
 	 * 
 	 *     ...
 	 * 
-	 * }
+ * } * * @since 1.5 * @@ -507,11 +507,11 @@ public String toString() { * Builder for creating a way-point with different parameters. *

* Creating a {@code WayPoint}: - *

{@code
+	 * {@snippet lang="java":
 	 * final WayPoint point = WayPoint.builder()
 	 *     .lat(48.2081743).lon(16.3738189).ele(160)
 	 *     .build();
-	 * }
+ * } * * @see #builder() */ @@ -1259,11 +1259,11 @@ public Optional course() { /** * Sets the extensions object, which may be {@code null}. The root * element of the extensions document must be {@code extensions}. - *
{@code
+		 * {@snippet lang="java":
 		 * 
 		 *     ...
 		 * 
-		 * }
+ * } * * @since 1.5 * diff --git a/jpx/src/main/java/io/jenetics/jpx/XMLReader.java b/jpx/src/main/java/io/jenetics/jpx/XMLReader.java index 7e00de80..67024dc0 100644 --- a/jpx/src/main/java/io/jenetics/jpx/XMLReader.java +++ b/jpx/src/main/java/io/jenetics/jpx/XMLReader.java @@ -100,13 +100,13 @@ enum Type { /** * Read the given type from the underlying XML stream {@code reader}. * - *
{@code
+	 * {@snippet lang="java":
 	 * try (AutoCloseableXMLStreamReader xml = XML.reader(in)) {
 	 *     // Move XML stream to first element.
 	 *     xml.next();
 	 *     return reader.read(xml);
 	 * }
-	 * }
+ * } * * @param xml the underlying XML stream {@code reader} * @param lenient lenient read mode @@ -201,17 +201,17 @@ public String toString() { * Return a {@code Reader} for reading an attribute of an element. *

* XML - *

 {@code }
+ *
 {@code }
 	 *
 	 * Reader definition
-	 * 
{@code
+	 * {@snippet lang="java":
 	 * final Reader reader =
 	 *     elem(
 	 *         v -> (Integer)v[0],
 	 *         "element",
 	 *         attr("length").map(Integer::parseInt)
 	 *     );
-	 * }
+ * } * * @param name the attribute name * @return an attribute reader @@ -225,17 +225,17 @@ public static XMLReader attr(final String name) { * Return a {@code Reader} for reading the text of an element. *

* XML - *

 {@code 1234}
+ *
 {@code 1234}
 	 *
 	 * Reader definition
-	 * 
{@code
+	 * {@snippet lang="java":
 	 * final Reader reader =
 	 *     elem(
 	 *         v -> (Integer)v[0],
 	 *         "element",
 	 *         text().map(Integer::parseInt)
 	 *     );
-	 * }
+ * } * * @return an element text reader */ @@ -249,10 +249,10 @@ public static XMLReader text() { * *

* XML - *

 {@code 1234}
+ *
 {@code 1234}
 	 *
 	 * Reader definition
-	 * 
{@code
+	 * {@snippet lang="java":
 	 * final XMLReader reader =
 	 *     elem(
 	 *         v -> {
@@ -264,7 +264,7 @@ public static XMLReader text() {
 	 *         attr("name"),
 	 *         text().map(Integer::parseInt)
 	 *     );
-	 * }
+ * } * * @param generator the generator function, which build the result object * from the given parameter array @@ -294,10 +294,10 @@ public static XMLReader elem( * the given parent element {@code name}. *

* XML - *

 {@code 1234}
+ *
 {@code 1234}
 	 *
 	 * Reader definition
-	 * 
{@code
+	 * {@snippet lang="java":
 	 * final XMLReader reader =
 	 *     elem("min",
 	 *         elem(
@@ -311,7 +311,7 @@ public static  XMLReader elem(
 	 *             text().map(Integer::parseInt)
 	 *         )
 	 *     );
-	 * }
+ * } * * @param name the parent element name * @param reader the child elements reader @@ -356,17 +356,17 @@ public static XMLReader ignore(final String name) { * -957346595 * -88668137 * - * } + * } * * Reader definition - *
{@code
+	 * {@snippet lang="java":
 	 * XMLReader> reader =
 	 *     elem(
 	 *         v -> (List)v[0],
 	 *         "properties",
 	 *         elems(elem("property", text().map(Integer::parseInt)))
 	 *     );
-	 * }
+ * } * * @param reader the child element reader * @param the element type diff --git a/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java b/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java index 5b7a6eef..849910be 100644 --- a/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java +++ b/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java @@ -110,9 +110,9 @@ void write(final XMLStreamWriter xml, final T data) * Writes the attribute with the given {@code name} to the current * outer element. * - *
{@code
+	 * {@snippet lang="java":
 	 * final XMLWriter writer1 = elem("element", attr("attribute"));
-	 * }
+ * } * * @param name the attribute name * @param the writer base type diff --git a/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java b/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java index 766779fc..be5a55b4 100644 --- a/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java +++ b/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java @@ -254,12 +254,12 @@ public Length distance(final Point start, final Point end) { * Return a collector which calculates the length of the (open) path which * is defined by the {@code Point} stream. * - *
{@code
+	 * {@snippet lang="java":
 	 * final Length length = gpx.tracks()
 	 *     .flatMap(Track::segments)
 	 *     .flatMap(TrackSegment::points)
 	 *     .collect(Geoid.WGSC_84.toPathLength());
-	 * }
+ * } * * The returned {@code Collector} doesn't work for parallel * stream. Using it for a parallel point stream will throw an @@ -283,12 +283,12 @@ public Length distance(final Point start, final Point end) { * is defined by the {@code Point} stream. The tour length * additionally adds the distance of the last point back to the first point. * - *
{@code
+	 * {@snippet lang="java":
 	 * final Length length = gpx.tracks()
 	 *     .flatMap(Track::segments)
 	 *     .flatMap(TrackSegment::points)
 	 *     .collect(Geoid.WGSC_84.toTourLength());
-	 * }
+ * } * * The returned {@code Collector} doesn't work for parallel * stream. Using it for a parallel point stream will throw an diff --git a/jpx/src/main/java/module-info.java b/jpx/src/main/java/module-info.java index ec31f577..4f7a2372 100644 --- a/jpx/src/main/java/module-info.java +++ b/jpx/src/main/java/module-info.java @@ -30,7 +30,7 @@ * Examples: *

* Creating a GPX object with one track-segment and 3 track-points - *

{@code
+ * {@snippet lang="java":
  * final GPX gpx = GPX.builder()
  *     .addTrack(track -> track
  *         .addSegment(segment -> segment
@@ -38,16 +38,16 @@
  *             .addPoint(p -> p.lat(48.20112).lon(16.31639).ele(278))
  *             .addPoint(p -> p.lat(48.20126).lon(16.31601).ele(274))))
  *     .build();
- * }
+ * } * * Writing a GPX file - *
{@code
+ * {@snippet lang="java":
  * final var indent = new GPX.Writer.Indent("    ");
  * GPX.Writer.of(indent).write(gpx, Path.of("points.gpx"));
- * }
+ * } * * This will produce the following output. - *
{@code
+ * {@snippet lang="java":
  * 
  *     
  *         
@@ -63,20 +63,20 @@
  *         
  *     
  * 
- * }
+ * } * * Reading a GPX file - *
{@code
+ * {@snippet lang="java":
  * final GPX gpx = GPX.read("points.xml");
- * }
+ * } * * Reading erroneous GPX files - *
{@code
+ * {@snippet lang="java":
  * final GPX gpx = GPX.Reader.of(GPX.Reader.Mode.LENIENT).read("track.xml");
- * }
+ * } * * This allows to read otherwise invalid GPX files, like - *
{@code
+ * {@snippet lang="java":
  * 
  * 
  *   
@@ -108,10 +108,10 @@
  *     
  *   
  * 
- * }
+ * } * * which is read as (if you write it again) - *
{@code
+ * {@snippet lang="java":
  * 
  * 
  *     
@@ -143,10 +143,10 @@
  *         
  *     
  * 
- * }
+ * } * * Converting a GPX object to an XML {@link org.w3c.dom.Document} - *
{@code
+ * {@snippet lang="java":
  * final GPX gpx = ...;
  *
  * final Document doc = XMLProvider.provider()
@@ -156,7 +156,7 @@
  *
  * // The GPX data are written to the empty `doc` object.
  * GPX.Writer.DEFAULT.write(gpx, new DOMResult(doc));
- * }
+ * } */ module io.jenetics.jpx { requires transitive java.xml; From 5eaa9fccf14666c1c8442ce45b10fdbd31b69d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 19:53:01 +0100 Subject: [PATCH 07/26] #174: Remove unused plugin. --- build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7b67afe7..d411de94 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,7 +25,6 @@ */ plugins { base - id("me.champeau.jmh") version "0.7.2" apply false } rootProject.version = JPX.VERSION From 87be51d0e8cea3f698ca6376d28657da21825bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 20:29:33 +0100 Subject: [PATCH 08/26] #174: Improve Javadoc. --- jpx/src/main/java/io/jenetics/jpx/WayPoint.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java index 97a2de88..e3168310 100644 --- a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java +++ b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java @@ -118,7 +118,7 @@ public final class WayPoint implements Point, Serializable { * @param source source of data. Included to give user some idea of * reliability and accuracy of data. "Garmin eTrex", "USGS quad * Boston North", e.g. (optional) - * @param links links to additional information about the way-point. May be + * @param links links to additional information about the way-point. Maybe * empty, but not {@code null}. * @param symbol text of GPS symbol name. For interchange with other * programs, use the exact spelling of the symbol as displayed on the @@ -1771,8 +1771,8 @@ public static WayPoint of( public static WayPoint of(final Point point) { requireNonNull(point); - return point instanceof WayPoint - ? (WayPoint)point + return point instanceof WayPoint wp + ? wp : of( point.getLatitude(), point.getLongitude(), From 407040dc56494a4327cff2d7e69e67692b504d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 22:05:46 +0100 Subject: [PATCH 09/26] #177: Convert 'geom' classes to records. --- .../java/io/jenetics/jpx/geom/Ellipsoid.java | 98 ++++--------------- .../main/java/io/jenetics/jpx/geom/Geoid.java | 72 ++++---------- .../java/io/jenetics/jpx/geom/MathUtils.java | 2 +- 3 files changed, 38 insertions(+), 134 deletions(-) diff --git a/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java b/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java index eeddc3a8..8e15b16e 100644 --- a/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java +++ b/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java @@ -21,7 +21,6 @@ import static java.util.Objects.requireNonNull; -import java.io.Serial; import java.io.Serializable; /** @@ -33,14 +32,18 @@ * @see Earth ellipsoid * @see Geoid * + * @param name the name of the earth ellipsoid model + * @param A the equatorial radius, in meter + * @param B the polar radius, in meter + * @param F the inverse flattening + * * @author Franz Wilhelmstötter - * @version 1.0 + * @version !__version__! * @since 1.0 */ -public final class Ellipsoid implements Serializable { - - @Serial - private static final long serialVersionUID = 1L; +public record Ellipsoid(String name, double A, double B, double F) + implements Serializable +{ /** * The ellipsoid of the World Geodetic System: WGS 84 @@ -48,7 +51,7 @@ public final class Ellipsoid implements Serializable { * @see * WGS-84 */ - public static final Ellipsoid WGS84 = of( + public static final Ellipsoid WGS84 = new Ellipsoid( "WGS-84", 6_378_137, 6_356_752.314245, @@ -61,7 +64,7 @@ public final class Ellipsoid implements Serializable { * * @see IERS-89 */ - public static final Ellipsoid IERS_1989 = of( + public static final Ellipsoid IERS_1989 = new Ellipsoid( "IERS-1989", 6_378_136, 6_356_751.302, @@ -74,7 +77,7 @@ public final class Ellipsoid implements Serializable { * * @see IERS-89 */ - public static final Ellipsoid IERS_2003 = of( + public static final Ellipsoid IERS_2003 = new Ellipsoid( "IERS-2003", 6_378_136.6, 6_356_751.9, @@ -86,84 +89,17 @@ public final class Ellipsoid implements Serializable { */ public static final Ellipsoid DEFAULT = WGS84; - private final String _name; - private final double _a; - private final double _b; - private final double _f; - /** * Create a new earth ellipsoid with the given parameters. * * @param name the name of the earth ellipsoid model - * @param a the equatorial radius, in meter - * @param b the polar radius, in meter - * @param f the inverse flattening + * @param A the equatorial radius, in meter + * @param B the polar radius, in meter + * @param F the inverse flattening * @throws NullPointerException if the given {@code name} is {@code null} */ - private Ellipsoid( - final String name, - final double a, - final double b, - final double f - ) { - _name = requireNonNull(name); - _a = a; - _b = b; - _f = f; - } - - /** - * Return the name of the earth ellipsoid model. - * - * @return the name of the earth ellipsoid model - */ - public String getName() { - return _name; - } - - /** - * Return the equatorial radius, in meter. - * - * @return the equatorial radius, in meter - */ - public double A() { - return _a; - } - - /** - * Return the polar radius, in meter. - * - * @return the polar radius, in meter - */ - public double B() { - return _b; - } - - /** - * Return the inverse flattening. - * - * @return the inverse flattening - */ - public double F() { - return _f; - } - - /** - * Create a new earth ellipsoid with the given parameters. - * - * @param name the name of the earth ellipsoid model - * @param a the equatorial radius, in meter - * @param b the polar radius, in meter - * @param f the inverse flattening - * @return a new earth ellipsoid with the given parameters - */ - public static Ellipsoid of( - final String name, - final double a, - final double b, - final double f - ) { - return new Ellipsoid(name, a, b, f); + public Ellipsoid { + requireNonNull(name); } } diff --git a/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java b/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java index be5a55b4..63be0923 100644 --- a/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java +++ b/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java @@ -31,6 +31,7 @@ import static java.util.Objects.requireNonNull; import static io.jenetics.jpx.geom.MathUtils.equal; +import java.io.Serializable; import java.util.stream.Collector; import io.jenetics.jpx.Length; @@ -43,11 +44,13 @@ * @see Wikipedia: Geoid * @see Ellipsoid * + * @param ellipsoid the ellipsoid used by the geoid + * * @author Franz Wilhelmstötter - * @version 1.0 + * @version !__version__! * @since 1.0 */ -public final class Geoid { +public record Geoid(Ellipsoid ellipsoid) implements Serializable { private static final int EPSILON_ULP = 10_000; @@ -57,7 +60,7 @@ public final class Geoid { * @see * WGS-84 */ - public static final Geoid WGS84 = of(Ellipsoid.WGS84); + public static final Geoid WGS84 = new Geoid(Ellipsoid.WGS84); /** * {@link Geoid} using the International Earth Rotation and Reference @@ -65,7 +68,7 @@ public final class Geoid { * * @see IERS-89 */ - public static final Geoid IERS_1989 = of(Ellipsoid.IERS_1989); + public static final Geoid IERS_1989 = new Geoid(Ellipsoid.IERS_1989); /** * {@link Geoid} using the International Earth Rotation and Reference @@ -73,22 +76,12 @@ public final class Geoid { * * @see IERS-89 */ - public static final Geoid IERS_2003 = of(Ellipsoid.IERS_2003); + public static final Geoid IERS_2003 = new Geoid(Ellipsoid.IERS_2003); /** * {@link Geoid} using the {@link Ellipsoid#DEFAULT} ellipsoid. */ - public static final Geoid DEFAULT = of(Ellipsoid.DEFAULT); - - private final Ellipsoid _ellipsoid; - - // Minor semi-axes of the ellipsoid. - private final double B; - - private final double AABBBB; - - // Flattening (A - B)/A - private final double F; + public static final Geoid DEFAULT = new Geoid(Ellipsoid.DEFAULT); // The maximal iteration of the 'distance' private static final int DISTANCE_ITERATION_MAX = 1000; @@ -102,26 +95,8 @@ public final class Geoid { * @param ellipsoid the ellipsoid used by the geoid * @throws NullPointerException if the given {@code ellipsoid} is {@code null} */ - private Geoid(final Ellipsoid ellipsoid) { - _ellipsoid = requireNonNull(ellipsoid); - - final double a = ellipsoid.A(); - final double aa = a*a; - - B = ellipsoid.B(); - final double bb = B*B; - - AABBBB = (aa - bb)/bb; - F = 1.0/ellipsoid.F(); - } - - /** - * Return the ellipsoid the {@code Geom} object is using. - * - * @return the ellipsoid the {@code Geom} object is using - */ - public Ellipsoid ellipsoid() { - return _ellipsoid; + public Geoid { + requireNonNull(ellipsoid); } /** @@ -145,6 +120,14 @@ public Ellipsoid ellipsoid() { * which is the case for a point and its (near) antidote. */ public Length distance(final Point start, final Point end) { + final double aa = ellipsoid.A()*ellipsoid.A(); + + final double B = ellipsoid.B(); + final double bb = B*B; + + final double AABB_BB = (aa - bb)/bb; + final double F = 1.0/ellipsoid.F(); + final double lat1 = start.getLatitude().toRadians(); final double lon1 = start.getLongitude().toRadians(); final double lat2 = end.getLatitude().toRadians(); @@ -211,7 +194,7 @@ public Length distance(final Point start, final Point end) { final double cos2sigmam = equal(cos2alpha, 0.0, EPSILON_ULP) ? 0.0 : cossigma - 2*sinU1sinU2/cos2alpha; - final double u2 = cos2alpha*AABBBB; + final double u2 = cos2alpha*AABB_BB; final double cos2sigmam2 = cos2sigmam*cos2sigmam; @@ -253,7 +236,6 @@ public Length distance(final Point start, final Point end) { /** * Return a collector which calculates the length of the (open) path which * is defined by the {@code Point} stream. - * * {@snippet lang="java": * final Length length = gpx.tracks() * .flatMap(Track::segments) @@ -282,7 +264,6 @@ public Length distance(final Point start, final Point end) { * Return a collector which calculates the length of the (closed) tour which * is defined by the {@code Point} stream. The tour length * additionally adds the distance of the last point back to the first point. - * * {@snippet lang="java": * final Length length = gpx.tracks() * .flatMap(Track::segments) @@ -307,17 +288,4 @@ public Length distance(final Point start, final Point end) { ); } - - - /** - * Create a new {@code Geoid} object with the given ellipsoid. - * - * @param ellipsoid the ellipsoid used by the geoid - * @return a new {@code Geoid} object with the given ellipsoid - * @throws NullPointerException if the given {@code ellipsoid} is {@code null} - */ - public static Geoid of(final Ellipsoid ellipsoid) { - return new Geoid(ellipsoid); - } - } diff --git a/jpx/src/main/java/io/jenetics/jpx/geom/MathUtils.java b/jpx/src/main/java/io/jenetics/jpx/geom/MathUtils.java index 3c8ff28c..02d1cedf 100644 --- a/jpx/src/main/java/io/jenetics/jpx/geom/MathUtils.java +++ b/jpx/src/main/java/io/jenetics/jpx/geom/MathUtils.java @@ -60,7 +60,7 @@ static boolean equal(final double x, final double y, final int ulps) { final long diffPositive = a - POSITIVE_ZERO_BITS; final long diffNegative = b - NEGATIVE_ZERO_BITS; equal = diffPositive <= ulps && diffNegative <= (ulps - diffPositive); - } else { // a and b have same sign. + } else { // a and b have the same sign. equal = a - b <= ulps; } From db19f84e944183c71e9786a7b7a24d02092028b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Tue, 7 Nov 2023 22:37:21 +0100 Subject: [PATCH 10/26] #177: Refactor to sealed types. --- .../jenetics/jpx/format/CompositeFormat.java | 4 +- .../io/jenetics/jpx/format/Elevation.java | 4 +- .../java/io/jenetics/jpx/format/Field.java | 14 ++- .../java/io/jenetics/jpx/format/Format.java | 13 ++- .../jpx/format/LocationFormatter.java | 103 ++++++++++-------- .../jenetics/jpx/format/LongitudeDegree.java | 6 +- .../jenetics/jpx/format/OptionalFormat.java | 4 +- 7 files changed, 91 insertions(+), 57 deletions(-) diff --git a/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java b/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java index 1160e2fe..e566b438 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java @@ -26,10 +26,10 @@ /** * @author Franz Wilhelmstötter - * @version 2.2 + * @version !__version__! * @since 1.4 */ -class CompositeFormat implements Format { +final class CompositeFormat implements Format { private final List _formats; diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java b/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java index b7af8aae..45db9c84 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java @@ -21,9 +21,9 @@ import java.util.Optional; /** - * This field allows to access the elevation (in meter) of a given location. + * This field allows accessing the elevation (in meter) of a given location. * - * @version 2.2 + * @version !__version__! * @since 2.2 */ final class Elevation extends Field { diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Field.java b/jpx/src/main/java/io/jenetics/jpx/format/Field.java index fb4a4b77..7756d92a 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Field.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Field.java @@ -34,10 +34,20 @@ * elevation. * * @author Franz Wilhelmstötter - * @version 3.0 + * @version !__version__! * @since 1.4 */ -abstract class Field implements Format { +abstract sealed class Field + implements Format + permits + Elevation, + LatitudeDegree, + LatitudeMinute, + LatitudeSecond, + LongitudeDegree, + LongitudeMinute, + LongitudeSecond +{ private static final DecimalFormatSymbols SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US); diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Format.java b/jpx/src/main/java/io/jenetics/jpx/format/Format.java index 3464b9d7..80d51687 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Format.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Format.java @@ -26,10 +26,19 @@ * Base interface for formatting and parsing a location. * * @author Franz Wilhelmstötter - * @version 2.2 + * @version !__version__! * @since 1.4 */ -interface Format { +sealed interface Format + permits + CompositeFormat, + ConstFormat, + Field, + LatitudeNS, + LongitudeEW, + OptionalFormat, + Plus +{ /** * Formats the given {@code value} to its string representation. If it is not diff --git a/jpx/src/main/java/io/jenetics/jpx/format/LocationFormatter.java b/jpx/src/main/java/io/jenetics/jpx/format/LocationFormatter.java index bf610652..b6def30a 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/LocationFormatter.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/LocationFormatter.java @@ -650,52 +650,67 @@ private void validate(){ Elevation E = null; for (var format : _formats) { - if (format instanceof LatitudeDegree ld) { - if (D == null) { - D = ld; - } else { - throw iae("Only one 'D' pattern allowed."); + switch (format) { + case LatitudeDegree latd -> { + if (D == null) { + D = latd; + } else { + throw iae("Only one 'D' pattern allowed."); + } + } + case LatitudeMinute latm -> { + if (M == null) { + M = latm; + } else { + throw iae("Only one 'M' pattern allowed."); + } } - } else if (format instanceof LatitudeMinute lm) { - if (M == null) { - M = lm; - } else { - throw iae("Only one 'M' pattern allowed."); + case LatitudeSecond lats -> { + if (S == null) { + S = lats; + } else { + throw iae("Only one 'S' pattern allowed."); + } + } + case LatitudeNS latns -> { + if (X == null) { + X = (LatitudeNS)format; + } } - } else if (format instanceof LatitudeSecond ls) { - if (S == null) { - S = ls; - } else { - throw iae("Only one 'S' pattern allowed."); + case LongitudeDegree lond -> { + if (d == null) { + d = lond; + } else { + throw iae("Only one 'd' pattern allowed."); + } } - } else if (format instanceof LatitudeNS && X==null) { - X = (LatitudeNS)format; - } else if (format instanceof LongitudeDegree ld) { - if (d == null) { - d = ld; - } else { - throw iae("Only one 'd' pattern allowed."); + case LongitudeMinute lonm -> { + if (m == null) { + m = lonm; + } else { + throw iae("Only one 'm' pattern allowed."); + } } - } else if (format instanceof LongitudeMinute lm) { - if (m == null) { - m = lm; - } else { - throw iae("Only one 'm' pattern allowed."); + case LongitudeSecond lons -> { + if (s == null) { + s = lons; + } else { + throw iae("Only one 's' pattern allowed."); + } } - } else if (format instanceof LongitudeSecond ls) { - if (s == null) { - s = ls; - } else { - throw iae("Only one 's' pattern allowed."); + case LongitudeEW lonew -> { + if (x == null) { + x = lonew; + } } - } else if (format instanceof LongitudeEW lew && x == null) { - x = lew; - } else if (format instanceof Elevation ele) { - if (E == null) { - E = ele; - } else { - throw iae("Only one 'E' pattern allowed."); + case Elevation ele -> { + if (E == null) { + E = ele; + } else { + throw iae("Only one 'E' pattern allowed."); + } } + default -> { } } } @@ -915,7 +930,7 @@ static List tokenize(final String pattern) { switch (c) { case '\'': quote = !quote; - if (token.length() > 0) { + if (!token.isEmpty()) { tokens.add(token.toString()); token.setLength(0); } @@ -925,7 +940,7 @@ static List tokenize(final String pattern) { if (quote) { token.append(c); } else { - if (token.length() > 0) { + if (!token.isEmpty()) { tokens.add(token.toString()); token.setLength(0); } @@ -939,7 +954,7 @@ static List tokenize(final String pattern) { pc != ',' && !quote) { - if (token.length() > 0) { + if (!token.isEmpty()) { tokens.add(token.toString()); token.setLength(0); } @@ -951,7 +966,7 @@ static List tokenize(final String pattern) { break; default: if (PROTECTED_CHARS.contains(pc) || pc == '\'') { - if (token.length() > 0) { + if (!token.isEmpty()) { tokens.add(token.toString()); token.setLength(0); } @@ -963,7 +978,7 @@ static List tokenize(final String pattern) { pc = c; } - if (token.length() > 0) { + if (!token.isEmpty()) { tokens.add(token.toString()); } diff --git a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java index 17286858..afc01cd9 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java @@ -23,16 +23,16 @@ import io.jenetics.jpx.Longitude; /** - * This field allows to access the longitude degrees of a given location. If the + * This field allows accessing the longitude degrees of a given location. If the * pattern has a fractional part, the longitude is rounded to match the pattern. * If the pattern has no fractional part, the longitude is truncated rather than * rounded, on the assumption that the fractional part will be represented by * minutes and seconds. * - * @version 2.2 + * @version !__version__! * @since 2.2 */ -class LongitudeDegree extends Field { +final class LongitudeDegree extends Field { LongitudeDegree(final String pattern) { super(pattern, 'd'); diff --git a/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java b/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java index c9ed4aa0..9dcb4f5d 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java @@ -27,10 +27,10 @@ /** * @author Franz Wilhelmstötter - * @version 2.2 + * @version !__version__! * @since 1.4 */ -class OptionalFormat implements Format { +final class OptionalFormat implements Format { private final Format _format; From 1dc1e3960d851290dea28bbeea1836319fc89db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Wed, 8 Nov 2023 21:42:52 +0100 Subject: [PATCH 11/26] Update version placeholder. --- jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java | 2 +- jpx/src/main/java/io/jenetics/jpx/format/Elevation.java | 2 +- jpx/src/main/java/io/jenetics/jpx/format/Field.java | 2 +- jpx/src/main/java/io/jenetics/jpx/format/Format.java | 2 +- jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java | 2 +- jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java | 2 +- jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java | 2 +- jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java b/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java index e566b438..c29bba1a 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java @@ -26,7 +26,7 @@ /** * @author Franz Wilhelmstötter - * @version !__version__! + * @version 4.0 * @since 1.4 */ final class CompositeFormat implements Format { diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java b/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java index 45db9c84..04975c26 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Elevation.java @@ -23,7 +23,7 @@ /** * This field allows accessing the elevation (in meter) of a given location. * - * @version !__version__! + * @version 4.0 * @since 2.2 */ final class Elevation extends Field { diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Field.java b/jpx/src/main/java/io/jenetics/jpx/format/Field.java index 7756d92a..f65a2dc3 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Field.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Field.java @@ -34,7 +34,7 @@ * elevation. * * @author Franz Wilhelmstötter - * @version !__version__! + * @version 4.0 * @since 1.4 */ abstract sealed class Field diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Format.java b/jpx/src/main/java/io/jenetics/jpx/format/Format.java index 80d51687..817b3c24 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Format.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Format.java @@ -26,7 +26,7 @@ * Base interface for formatting and parsing a location. * * @author Franz Wilhelmstötter - * @version !__version__! + * @version 4.0 * @since 1.4 */ sealed interface Format diff --git a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java index afc01cd9..b1c260c9 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeDegree.java @@ -29,7 +29,7 @@ * rounded, on the assumption that the fractional part will be represented by * minutes and seconds. * - * @version !__version__! + * @version 4.0 * @since 2.2 */ final class LongitudeDegree extends Field { diff --git a/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java b/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java index 9dcb4f5d..f6586ee3 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/OptionalFormat.java @@ -27,7 +27,7 @@ /** * @author Franz Wilhelmstötter - * @version !__version__! + * @version 4.0 * @since 1.4 */ final class OptionalFormat implements Format { diff --git a/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java b/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java index 8e15b16e..ceecb662 100644 --- a/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java +++ b/jpx/src/main/java/io/jenetics/jpx/geom/Ellipsoid.java @@ -38,7 +38,7 @@ * @param F the inverse flattening * * @author Franz Wilhelmstötter - * @version !__version__! + * @version 4.0 * @since 1.0 */ public record Ellipsoid(String name, double A, double B, double F) diff --git a/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java b/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java index 63be0923..78729fe0 100644 --- a/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java +++ b/jpx/src/main/java/io/jenetics/jpx/geom/Geoid.java @@ -47,7 +47,7 @@ * @param ellipsoid the ellipsoid used by the geoid * * @author Franz Wilhelmstötter - * @version !__version__! + * @version 4.0 * @since 1.0 */ public record Geoid(Ellipsoid ellipsoid) implements Serializable { From 204c33577b9ab2ecd2324295925c5ac10641af84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Wed, 8 Nov 2023 22:39:23 +0100 Subject: [PATCH 12/26] Improve Javadoc. --- jpx/src/main/java/io/jenetics/jpx/GPX.java | 2 +- jpx/src/main/java/io/jenetics/jpx/Person.java | 8 ++++---- .../main/java/io/jenetics/jpx/format/LatitudeMinute.java | 2 +- .../main/java/io/jenetics/jpx/format/LatitudeSecond.java | 2 +- jpx/src/main/java/io/jenetics/jpx/format/Location.java | 2 +- .../main/java/io/jenetics/jpx/format/LongitudeMinute.java | 2 +- .../main/java/io/jenetics/jpx/format/LongitudeSecond.java | 2 +- jpx/src/main/java/io/jenetics/jpx/package-info.java | 2 +- jpx/src/main/java/module-info.java | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/jpx/src/main/java/io/jenetics/jpx/GPX.java b/jpx/src/main/java/io/jenetics/jpx/GPX.java index 080d9373..7cc63e8a 100644 --- a/jpx/src/main/java/io/jenetics/jpx/GPX.java +++ b/jpx/src/main/java/io/jenetics/jpx/GPX.java @@ -2076,7 +2076,7 @@ public static void write(final GPX gpx, final Path path) throws IOException { } /** - * Read an GPX object from the given {@code input} stream. + * Read a GPX object from the given {@code input} stream. * This method is a shortcut for * {@snippet lang="java": * GPX.Reader.DEFAULT.read(path); diff --git a/jpx/src/main/java/io/jenetics/jpx/Person.java b/jpx/src/main/java/io/jenetics/jpx/Person.java index 7e88aa21..257739f0 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Person.java +++ b/jpx/src/main/java/io/jenetics/jpx/Person.java @@ -52,7 +52,7 @@ public final class Person implements Serializable { * * @param name name of person or organization * @param email the person's email address - * @param link link to Web site or other external information about person + * @param link link to website or other external information about person */ private Person(final String name, final Email email, final Link link) { _name = name; @@ -79,9 +79,9 @@ public Optional getEmail() { } /** - * Return the link to Web site or other external information about person. + * Return the link to website or other external information about person. * - * @return the link to Web site or other external information about person + * @return the link to website or other external information about person */ public Optional getLink() { return Optional.ofNullable(_link); @@ -137,7 +137,7 @@ public String toString() { * * @param name name of person or organization * @param email the person's email address - * @param link link to Web site or other external information about person + * @param link link to website or other external information about person * @return a new {@code Person} object with the given parameters */ public static Person of(final String name, final Email email, final Link link) { diff --git a/jpx/src/main/java/io/jenetics/jpx/format/LatitudeMinute.java b/jpx/src/main/java/io/jenetics/jpx/format/LatitudeMinute.java index 7195c702..9684fb67 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/LatitudeMinute.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/LatitudeMinute.java @@ -21,7 +21,7 @@ import io.jenetics.jpx.Latitude; /** - * This field allows to access the absolute value of the minute part of the + * This field allows accessing the absolute value of the minute part of the * latitude of a given location. * * @version 2.2 diff --git a/jpx/src/main/java/io/jenetics/jpx/format/LatitudeSecond.java b/jpx/src/main/java/io/jenetics/jpx/format/LatitudeSecond.java index 82d999f2..f331fc93 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/LatitudeSecond.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/LatitudeSecond.java @@ -21,7 +21,7 @@ import io.jenetics.jpx.Latitude; /** - * This field allows to access the absolute value of the second part of the + * This field allows accessing the absolute value of the second part of the * latitude of a given location. * * @version 2.2 diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Location.java b/jpx/src/main/java/io/jenetics/jpx/format/Location.java index 1397a747..e7a179b2 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Location.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Location.java @@ -128,7 +128,7 @@ public String toString() { * Create a new location form the given GPS point. * * @param point the GPS point - * @return a new location form the given GPS point + * @return a new location from the given GPS point * @throws NullPointerException if the given {@code point} is {@code null} */ public static Location of(final Point point) { diff --git a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeMinute.java b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeMinute.java index cec7a6e2..d92c4a24 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeMinute.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeMinute.java @@ -21,7 +21,7 @@ import io.jenetics.jpx.Longitude; /** - * This field allows to access the absolute value of the minute part of the + * This field allows accessing the absolute value of the minute part of the * longitude of a given location. * * @version 2.2 diff --git a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeSecond.java b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeSecond.java index c78354c8..e372b930 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/LongitudeSecond.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/LongitudeSecond.java @@ -21,7 +21,7 @@ import io.jenetics.jpx.Longitude; /** - * This field allows to access the absolute value of the second part of the + * This field allows accessing the absolute value of the second part of the * longitude of a given location. * * @version 2.2 diff --git a/jpx/src/main/java/io/jenetics/jpx/package-info.java b/jpx/src/main/java/io/jenetics/jpx/package-info.java index fd1fb681..fb2888dc 100644 --- a/jpx/src/main/java/io/jenetics/jpx/package-info.java +++ b/jpx/src/main/java/io/jenetics/jpx/package-info.java @@ -21,7 +21,7 @@ /** * This is the base package of the * JPX library. It contains the domain objects which are needed - * for fully modelling of the + * for full modeling of the * GPX standard 1.1 and * 1.0. * diff --git a/jpx/src/main/java/module-info.java b/jpx/src/main/java/module-info.java index 4f7a2372..3a92d48a 100644 --- a/jpx/src/main/java/module-info.java +++ b/jpx/src/main/java/module-info.java @@ -21,7 +21,7 @@ * format. It is a full implementation of version * 1.1 and version * 1.0 of the GPX format. - * The data classes are completely immutable and allows a functional programming + * The data classes are completely immutable and allow a functional programming * style. It is also possible to convert the location information into strings * which are compatible to the * ISO 6709 standard. From db19cd0c840473750328d54a1a300e1ff01b0e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sat, 16 Nov 2024 23:24:34 +0100 Subject: [PATCH 13/26] Update used libraries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- gradle/libs.versions.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9d42c88d..f1734af3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,10 +4,10 @@ jmh = { id = "me.champeau.jmh", version = "0.7.2" } [libraries] -assertj = "org.assertj:assertj-core:3.24.2" +assertj = "org.assertj:assertj-core:3.26.3" commons-math = "org.apache.commons:commons-math3:3.6.1" -equalsverifier = "nl.jqno.equalsverifier:equalsverifier:3.15.3" -guava = "com.google.guava:guava:32.1.3-jre" +equalsverifier = "nl.jqno.equalsverifier:equalsverifier:3.17.3" +guava = "com.google.guava:guava:32.3.1-jre" prngine = "io.jenetics:prngine:2.0.0" rxjava = "io.reactivex.rxjava2:rxjava:2.2.21" -testng = "org.testng:testng:7.8.0" +testng = "org.testng:testng:7.10.2" From 8ca1e95315a974f82dbc03bbcc207f61049bf4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 24 Aug 2025 21:33:16 +0200 Subject: [PATCH 14/26] Update Gradle to 9.0. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 11 ----------- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3a80b5c9..f4bed36b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,7 @@ plugins { rootProject.version = JPX.VERSION tasks.named("wrapper") { - version = "8.11" + version = "9.0.0" distributionType = Wrapper.DistributionType.ALL } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 372fd0d8..c95b4672 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -35,14 +35,3 @@ repositories { mavenLocal() gradlePluginPortal() } - -tasks.withType { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_17) - } -} - -configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7cf748e7..48b43d35 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 9c090154a8a54e5b98df6a8223c58c580ebc3e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 24 Aug 2025 21:36:32 +0200 Subject: [PATCH 15/26] Update dependency management. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 1 + gradle/libs.versions.toml | 91 ++++++++++++++++++++++++++++++++++----- jpx/build.gradle.kts | 2 +- 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f4bed36b..69f999a5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,6 +28,7 @@ import io.jenetics.gradle.dsl.moduleName */ plugins { base + alias(libs.plugins.version.catalog.update) } rootProject.version = JPX.VERSION diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f1734af3..53454cf7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,13 +1,84 @@ -[plugins] +[versions] +assertj = "3.27.4" +codemodel = "4.0.5" +commons-csv = "1.14.1" +commons-math4-legacy = "4.0-beta1" +commons-numbers-combinatorics = "1.2" +commons-numbers-core = "1.2" +commons-numbers-gamma = "1.2" +commons-numbers-rootfinder = "1.2" +commons-rng-sampling = "1.6" +commons-rng-simple = "1.6" +commons-statistics-descriptive = "1.1" +commons-statistics-distribution = "1.1" +equalsverifier = "4.0.9" +facilejdbc = "2.1.1" +guava = "33.4.8-jre" +h2 = "2.3.232" +jackson = "2.19.2" +jackson-databind-nullable = "0.2.7" +jackson-datatype-jsr310 = "2.19.2" +jacoco-agent = "0.8.13" +jakarta-annotation-api = "3.0.0" +jakarta-validation-api = "3.1.1" +javacsv = "2.0" +jexl = "3.5.0" +jmh = "0.7.3" +jpx = "3.2.1" +lombok = "8.14.2" +mvel = "2.5.2.Final" +nashorn = "15.7" +openapi-generator = "7.14.0" +opencsv = "5.12.0" +prngine = "2.0.0" +reactor-core = "3.7.9" +rxjava = "2.2.21" +supercsv = "2.4.0" +swagger-models = "2.2.36" +swagger-parser = "2.1.32" +testng = "7.11.0" +version-catalog-update = "1.0.0" -jmh = { id = "me.champeau.jmh", version = "0.7.2" } +[plugins] +jmh = { id = "me.champeau.jmh", version.ref = "jmh" } +lombok = { id = "io.freefair.lombok", version.ref = "lombok" } +openapi-generator = { id = "org.openapi.generator", version.ref = "openapi-generator" } +version-catalog-update = { id = "nl.littlerobots.version-catalog-update", version.ref = "version-catalog-update" } [libraries] - -assertj = "org.assertj:assertj-core:3.26.3" -commons-math = "org.apache.commons:commons-math3:3.6.1" -equalsverifier = "nl.jqno.equalsverifier:equalsverifier:3.17.3" -guava = "com.google.guava:guava:32.3.1-jre" -prngine = "io.jenetics:prngine:2.0.0" -rxjava = "io.reactivex.rxjava2:rxjava:2.2.21" -testng = "org.testng:testng:7.10.2" +assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" } +codemodel = { module = "org.glassfish.jaxb:codemodel", version.ref = "codemodel" } +commons-csv = { module = "org.apache.commons:commons-csv", version.ref = "commons-csv" } +commons-math4-legacy = { module = "org.apache.commons:commons-math4-legacy", version.ref = "commons-math4-legacy" } +commons-numbers-combinatorics = { module = "org.apache.commons:commons-numbers-combinatorics", version.ref = "commons-numbers-combinatorics" } +commons-numbers-core = { module = "org.apache.commons:commons-numbers-core", version.ref = "commons-numbers-core" } +commons-numbers-gamma = { module = "org.apache.commons:commons-numbers-gamma", version.ref = "commons-numbers-gamma" } +commons-numbers-rootfinder = { module = "org.apache.commons:commons-numbers-rootfinder", version.ref = "commons-numbers-rootfinder" } +commons-rng-sampling = { module = "org.apache.commons:commons-rng-sampling", version.ref = "commons-rng-sampling" } +commons-rng-simple = { module = "org.apache.commons:commons-rng-simple", version.ref = "commons-rng-simple" } +commons-statistics-descriptive = { module = "org.apache.commons:commons-statistics-descriptive", version.ref = "commons-statistics-descriptive" } +commons-statistics-distribution = { module = "org.apache.commons:commons-statistics-distribution", version.ref = "commons-statistics-distribution" } +equalsverifier = { module = "nl.jqno.equalsverifier:equalsverifier", version.ref = "equalsverifier" } +facilejdbc = { module = "io.jenetics:facilejdbc", version.ref = "facilejdbc" } +guava = { module = "com.google.guava:guava", version.ref = "guava" } +h2 = { module = "com.h2database:h2", version.ref = "h2" } +jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +jackson-databind-nullable = { module = "org.openapitools:jackson-databind-nullable", version.ref = "jackson-databind-nullable" } +jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson-datatype-jsr310" } +jacoco-agent = { module = "org.jacoco:org.jacoco.agent", version.ref = "jacoco-agent" } +jakarta-annotation-api = { module = "jakarta.annotation:jakarta.annotation-api", version.ref = "jakarta-annotation-api" } +jakarta-validation-api = { module = "jakarta.validation:jakarta.validation-api", version.ref = "jakarta-validation-api" } +javacsv = { module = "net.sourceforge.javacsv:javacsv", version.ref = "javacsv" } +jexl = { module = "org.apache.commons:commons-jexl3", version.ref = "jexl" } +jpx = { module = "io.jenetics:jpx", version.ref = "jpx" } +mvel = { module = "org.mvel:mvel2", version.ref = "mvel" } +nashorn-core = { module = "org.openjdk.nashorn:nashorn-core", version.ref = "nashorn" } +opencsv = { module = "com.opencsv:opencsv", version.ref = "opencsv" } +prngine = { module = "io.jenetics:prngine", version.ref = "prngine" } +reactor-core = { module = "io.projectreactor:reactor-core", version.ref = "reactor-core" } +rxjava = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjava" } +supercsv = { module = "net.sf.supercsv:super-csv", version.ref = "supercsv" } +swagger-models = { module = "io.swagger.core.v3:swagger-models", version.ref = "swagger-models" } +swagger-parser = { module = "io.swagger.parser.v3:swagger-parser", version.ref = "swagger-parser" } +testng = { module = "org.testng:testng", version.ref = "testng" } diff --git a/jpx/build.gradle.kts b/jpx/build.gradle.kts index b4ecd682..4e50acf0 100644 --- a/jpx/build.gradle.kts +++ b/jpx/build.gradle.kts @@ -36,7 +36,7 @@ description = "JPX - Java GPX (GPS) Library" moduleName = "io.jenetics.jpx" dependencies { - testImplementation(libs.assertj) + testImplementation(libs.assertj.core) testImplementation(libs.equalsverifier) testImplementation(libs.prngine) testImplementation(libs.testng) From d7bd5af968f02c1d567d0d4e872bc7223e634374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 24 Aug 2025 21:37:49 +0200 Subject: [PATCH 16/26] Update gradle.yml Update latest build version to Java 24. --- .github/workflows/gradle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 7c3d4ab1..8e26b458 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [ ubuntu-latest, macos-latest ] - java-version: [ 21, 23 ] + java-version: [ 21, 24 ] steps: - uses: actions/checkout@v2 @@ -27,4 +27,4 @@ jobs: java-version: ${{ matrix.java-version }} distribution: 'zulu' - name: Build with Gradle - run: ./gradlew build --stacktrace --info \ No newline at end of file + run: ./gradlew build --stacktrace --info From 97af57aaa4cf93e4af24c0aed57d80f5e906e87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 24 Aug 2025 21:45:04 +0200 Subject: [PATCH 17/26] Upgrade publishing scripts. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 64 ++++++++++--------- .../resources/javadoc/java.se/element-list | 4 +- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 69f999a5..7d79ba60 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,6 @@ import io.jenetics.gradle.dsl.isModule import io.jenetics.gradle.dsl.moduleName +import org.apache.tools.ant.filters.ReplaceTokens /* * Java GPX Library (@__identifier__@). @@ -9,7 +10,7 @@ import io.jenetics.gradle.dsl.moduleName * 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 + * 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, @@ -18,7 +19,7 @@ import io.jenetics.gradle.dsl.moduleName * limitations under the License. * * Author: - * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) + * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) */ /** @@ -28,7 +29,7 @@ import io.jenetics.gradle.dsl.moduleName */ plugins { base - alias(libs.plugins.version.catalog.update) + alias(libs.plugins.version.catalog.update) } rootProject.version = JPX.VERSION @@ -229,6 +230,9 @@ fun xlint(): String { val identifier = "${JPX.ID}-${JPX.VERSION}" +/** + * Setup of the Maven publishing. + */ /** * Setup of the Maven publishing. */ @@ -240,26 +244,29 @@ fun setupPublishing(project: Project) { project.tasks.named("sourcesJar") { filter( - org.apache.tools.ant.filters.ReplaceTokens::class, "tokens" to mapOf( - "__identifier__" to identifier, - "__year__" to Env.COPYRIGHT_YEAR - ) + ReplaceTokens::class, "tokens" to mapOf( + "__identifier__" to identifier, + "__year__" to Env.COPYRIGHT_YEAR + ) ) } project.tasks.named("javadocJar") { filter( - org.apache.tools.ant.filters.ReplaceTokens::class, "tokens" to mapOf( - "__identifier__" to identifier, - "__year__" to Env.COPYRIGHT_YEAR - ) + ReplaceTokens::class, "tokens" to mapOf( + "__identifier__" to identifier, + "__year__" to Env.COPYRIGHT_YEAR + ) ) } project.configure { publications { create("mavenJava") { - artifactId = JPX.ID + suppressPomMetadataWarningsFor("testFixturesApiElements") + suppressPomMetadataWarningsFor("testFixturesRuntimeElements") + + artifactId = project.name from(project.components["java"]) versionMapping { usage("java-api") { @@ -299,24 +306,23 @@ fun setupPublishing(project: Project) { } repositories { maven { - url = if (version.toString().endsWith("SNAPSHOT")) { - uri(Maven.SNAPSHOT_URL) - } else { - uri(Maven.RELEASE_URL) - } + url = if (version.toString().endsWith("SNAPSHOT")) + uri(layout.buildDirectory.dir("repos/snapshots")) + else + uri(layout.buildDirectory.dir("repos/releases")) + } + } - credentials { - username = if (extra.properties["nexus_username"] != null) { - extra.properties["nexus_username"] as String - } else { - "nexus_username" - } - password = if (extra.properties["nexus_password"] != null) { - extra.properties["nexus_password"] as String - } else { - "nexus_password" - } - } + // Exclude test fixtures from publication, as we use them only internally + plugins.withId("org.gradle.java-test-fixtures") { + val component = components["java"] as AdhocComponentWithVariants + component.withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { skip() } + component.withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { skip() } + + // Workaround to not publish test fixtures sources added by com.vanniktech.maven.publish plugin + // TODO: Remove as soon as https://github.com/vanniktech/gradle-maven-publish-plugin/issues/779 closed + afterEvaluate { + component.withVariantsFromConfiguration(configurations["testFixturesSourcesElements"]) { skip() } } } } diff --git a/buildSrc/resources/javadoc/java.se/element-list b/buildSrc/resources/javadoc/java.se/element-list index 9cf9ae2d..4d9e2fef 100644 --- a/buildSrc/resources/javadoc/java.se/element-list +++ b/buildSrc/resources/javadoc/java.se/element-list @@ -3,6 +3,7 @@ java.io java.lang java.lang.annotation java.lang.constant +java.lang.foreign java.lang.invoke java.lang.module java.lang.ref @@ -221,12 +222,9 @@ module:jdk.hotspot.agent module:jdk.httpserver com.sun.net.httpserver com.sun.net.httpserver.spi -module:jdk.incubator.foreign -jdk.incubator.foreign module:jdk.incubator.vector jdk.incubator.vector module:jdk.jartool -com.sun.jarsigner jdk.security.jarsigner module:jdk.javadoc jdk.javadoc.doclet From fac2d4b00179b4355277c6bcfe95bef1eea18c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 19:32:44 +0100 Subject: [PATCH 18/26] #192: Update Gradle to 9.3.1. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 43583 -> 45457 bytes gradlew | 11 +++++------ gradlew.bat | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7d79ba60..373c4a8a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -35,7 +35,7 @@ plugins { rootProject.version = JPX.VERSION tasks.named("wrapper") { - version = "9.0.0" + version = "9.3.1" distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b9530d66f5e68d973ea569d8e19de379189..8bdaf60c75ab801e22807dde59e12a8735a34077 100644 GIT binary patch delta 37330 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 diff --git a/gradlew b/gradlew index f5feea6d..ef07e016 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 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. @@ -86,8 +86,7 @@ done # 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 -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -206,7 +205,7 @@ fi 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, +# * DEFAULT_JVM_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. @@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9b42019c..5eed7ee8 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From 0ce640a7be1c6963ade1e9f0eaf36c22306dadd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 19:37:36 +0100 Subject: [PATCH 19/26] #192: Update libraries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 2 +- gradle/libs.versions.toml | 40 +++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 373c4a8a..6055f0e5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -133,7 +133,7 @@ fun setupTestReporting(project: Project) { project.apply(plugin = "jacoco") project.configure { - toolVersion = "0.8.12" + toolVersion = libs.jacoco.agent.get().version.toString() } project.tasks { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 53454cf7..7abf0665 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -assertj = "3.27.4" -codemodel = "4.0.5" +assertj = "3.27.7" +codemodel = "4.0.6" commons-csv = "1.14.1" commons-math4-legacy = "4.0-beta1" commons-numbers-combinatorics = "1.2" @@ -9,35 +9,35 @@ commons-numbers-gamma = "1.2" commons-numbers-rootfinder = "1.2" commons-rng-sampling = "1.6" commons-rng-simple = "1.6" -commons-statistics-descriptive = "1.1" -commons-statistics-distribution = "1.1" -equalsverifier = "4.0.9" +commons-statistics-descriptive = "1.2" +commons-statistics-distribution = "1.2" +equalsverifier = "4.4" facilejdbc = "2.1.1" -guava = "33.4.8-jre" -h2 = "2.3.232" -jackson = "2.19.2" -jackson-databind-nullable = "0.2.7" -jackson-datatype-jsr310 = "2.19.2" -jacoco-agent = "0.8.13" +guava = "33.5.0-jre" +h2 = "2.4.240" +jackson = "2.21" +jackson-databind-nullable = "0.2.9" +jackson-datatype-jsr310 = "2.21.0" +jacoco-agent = "0.8.14" jakarta-annotation-api = "3.0.0" jakarta-validation-api = "3.1.1" javacsv = "2.0" -jexl = "3.5.0" +jexl = "3.6.2" jmh = "0.7.3" jpx = "3.2.1" -lombok = "8.14.2" +lombok = "9.2.0" mvel = "2.5.2.Final" nashorn = "15.7" -openapi-generator = "7.14.0" +openapi-generator = "7.20.0" opencsv = "5.12.0" prngine = "2.0.0" -reactor-core = "3.7.9" +reactor-core = "3.8.3" rxjava = "2.2.21" supercsv = "2.4.0" -swagger-models = "2.2.36" -swagger-parser = "2.1.32" -testng = "7.11.0" -version-catalog-update = "1.0.0" +swagger-models = "2.2.43" +swagger-parser = "2.1.38" +testng = "7.12.0" +version-catalog-update = "1.1.0" [plugins] jmh = { id = "me.champeau.jmh", version.ref = "jmh" } @@ -63,7 +63,7 @@ facilejdbc = { module = "io.jenetics:facilejdbc", version.ref = "facilejdbc" } guava = { module = "com.google.guava:guava", version.ref = "guava" } h2 = { module = "com.h2database:h2", version.ref = "h2" } jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } -jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +jackson-databind = "com.fasterxml.jackson.core:jackson-databind:2.21.0" jackson-databind-nullable = { module = "org.openapitools:jackson-databind-nullable", version.ref = "jackson-databind-nullable" } jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson-datatype-jsr310" } jacoco-agent = { module = "org.jacoco:org.jacoco.agent", version.ref = "jacoco-agent" } From eb90d8e4c39541cc746ad1cdfd1c2d821cdefa56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 20:08:15 +0100 Subject: [PATCH 20/26] #192: Update to Java 25. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- build.gradle.kts | 6 +++--- buildSrc/resources/javadoc/java.se/element-list | 9 +++++++-- jpx/src/main/java/io/jenetics/jpx/Degrees.java | 7 ++++--- jpx/src/main/java/io/jenetics/jpx/Latitude.java | 7 ++++--- jpx/src/main/java/io/jenetics/jpx/Longitude.java | 7 ++++--- jpx/src/test/java/io/jenetics/jpx/DegreesTest.java | 7 ------- jpx/src/test/java/io/jenetics/jpx/LatitudeTest.java | 7 ------- jpx/src/test/java/io/jenetics/jpx/LongitudeTest.java | 7 ------- 8 files changed, 22 insertions(+), 35 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6055f0e5..c73d9273 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -72,8 +72,8 @@ gradle.projectsEvaluated { plugins.withType { configure { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 } configure { @@ -170,7 +170,7 @@ fun setupJavadoc(project: Project) { doclet.charSet = "UTF-8" doclet.linkSource(true) doclet.linksOffline( - "https://docs.oracle.com/en/java/javase/21/docs/api/", + "https://docs.oracle.com/en/java/javase/25/docs/api/", "${project.rootDir}/buildSrc/resources/javadoc/java.se" ) doclet.windowTitle = "JPX ${project.version}" diff --git a/buildSrc/resources/javadoc/java.se/element-list b/buildSrc/resources/javadoc/java.se/element-list index 4d9e2fef..0e170a3a 100644 --- a/buildSrc/resources/javadoc/java.se/element-list +++ b/buildSrc/resources/javadoc/java.se/element-list @@ -2,6 +2,10 @@ module:java.base java.io java.lang java.lang.annotation +java.lang.classfile +java.lang.classfile.attribute +java.lang.classfile.constantpool +java.lang.classfile.instruction java.lang.constant java.lang.foreign java.lang.invoke @@ -91,6 +95,7 @@ javax.print javax.print.attribute javax.print.attribute.standard javax.print.event +javax.sound javax.sound.midi javax.sound.midi.spi javax.sound.sampled @@ -210,7 +215,6 @@ com.sun.source.tree com.sun.source.util com.sun.tools.javac module:jdk.crypto.cryptoki -module:jdk.crypto.ec module:jdk.dynalink jdk.dynalink jdk.dynalink.beans @@ -255,6 +259,7 @@ module:jdk.jstatd module:jdk.localedata module:jdk.management com.sun.management +jdk.management module:jdk.management.agent module:jdk.management.jfr jdk.management.jfr @@ -279,4 +284,4 @@ org.w3c.dom.css org.w3c.dom.html org.w3c.dom.stylesheets org.w3c.dom.xpath -module:jdk.zipfs +module:jdk.zipfs \ No newline at end of file diff --git a/jpx/src/main/java/io/jenetics/jpx/Degrees.java b/jpx/src/main/java/io/jenetics/jpx/Degrees.java index 6905dcd4..40009c67 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Degrees.java +++ b/jpx/src/main/java/io/jenetics/jpx/Degrees.java @@ -76,7 +76,9 @@ public final class Degrees * range of {@code [0..360]} */ private Degrees(final double value) { - if (value < MIN_VALUE || value >= MAX_VALUE) { + if (Double.compare(value, MIN_VALUE) < 0 || + Double.compare(value, MAX_VALUE) >= 0) + { throw new IllegalArgumentException(format( "%f not in the range [0, 360).", value )); @@ -140,8 +142,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Degrees deg && + return obj instanceof Degrees deg && Double.compare(deg._value, _value) == 0; } diff --git a/jpx/src/main/java/io/jenetics/jpx/Latitude.java b/jpx/src/main/java/io/jenetics/jpx/Latitude.java index e890bf5d..1443d355 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Latitude.java +++ b/jpx/src/main/java/io/jenetics/jpx/Latitude.java @@ -84,7 +84,9 @@ public final class Latitude extends Number implements Serializable { * range of {@code [-90..90]} */ private Latitude(final double value) { - if (value < MIN_DEGREES || value > MAX_DEGREES) { + if (Double.compare(value, MIN_DEGREES) < 0 || + Double.compare(value, MAX_DEGREES) > 0) + { throw new IllegalArgumentException(format( "%f is not in range [-90, 90].", value )); @@ -143,8 +145,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Latitude lat && + return obj instanceof Latitude lat && Double.compare(lat._value, _value) == 0; } diff --git a/jpx/src/main/java/io/jenetics/jpx/Longitude.java b/jpx/src/main/java/io/jenetics/jpx/Longitude.java index 7d561f65..d2c4151b 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Longitude.java +++ b/jpx/src/main/java/io/jenetics/jpx/Longitude.java @@ -84,7 +84,9 @@ public final class Longitude extends Number implements Serializable { * range of {@code [-180..180]} */ private Longitude(final double value) { - if (value < MIN_DEGREES || value > MAX_DEGREES) { + if (Double.compare(value, MIN_DEGREES) < 0 || + Double.compare(value, MAX_DEGREES) > 0) + { throw new IllegalArgumentException(format( "%f is not in range [-180, 180).", value )); @@ -143,8 +145,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Longitude lng && + return obj instanceof Longitude lng && Double.compare(lng._value, _value) == 0; } diff --git a/jpx/src/test/java/io/jenetics/jpx/DegreesTest.java b/jpx/src/test/java/io/jenetics/jpx/DegreesTest.java index cbc19344..69dbc30a 100644 --- a/jpx/src/test/java/io/jenetics/jpx/DegreesTest.java +++ b/jpx/src/test/java/io/jenetics/jpx/DegreesTest.java @@ -19,8 +19,6 @@ */ package io.jenetics.jpx; -import nl.jqno.equalsverifier.EqualsVerifier; - import java.util.Random; import java.util.function.Supplier; @@ -68,9 +66,4 @@ public void ofDegrees() { ); } - @Test - public void equalsVerifier() { - EqualsVerifier.forClass(Degrees.class).verify(); - } - } diff --git a/jpx/src/test/java/io/jenetics/jpx/LatitudeTest.java b/jpx/src/test/java/io/jenetics/jpx/LatitudeTest.java index d9ca3b43..6db82c08 100644 --- a/jpx/src/test/java/io/jenetics/jpx/LatitudeTest.java +++ b/jpx/src/test/java/io/jenetics/jpx/LatitudeTest.java @@ -19,8 +19,6 @@ */ package io.jenetics.jpx; -import nl.jqno.equalsverifier.EqualsVerifier; - import java.util.Random; import java.util.function.Supplier; @@ -64,9 +62,4 @@ public void ofDegrees() { ); } - @Test - public void equalsVerifier() { - EqualsVerifier.forClass(Latitude.class).verify(); - } - } diff --git a/jpx/src/test/java/io/jenetics/jpx/LongitudeTest.java b/jpx/src/test/java/io/jenetics/jpx/LongitudeTest.java index a77021ef..dacc7002 100644 --- a/jpx/src/test/java/io/jenetics/jpx/LongitudeTest.java +++ b/jpx/src/test/java/io/jenetics/jpx/LongitudeTest.java @@ -22,8 +22,6 @@ import static java.lang.Double.doubleToLongBits; import static java.lang.Double.longBitsToDouble; -import nl.jqno.equalsverifier.EqualsVerifier; - import java.util.Random; import java.util.function.Supplier; @@ -76,9 +74,4 @@ public void ofDegrees() { ); } - @Test - public void equalsVerifier() { - EqualsVerifier.forClass(Longitude.class).verify(); - } - } From d307d048a1722f34c30f892c029cbae6f077e34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 20:14:14 +0100 Subject: [PATCH 21/26] #192: Remvove 'obj == this' from equals methods. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- jpx/src/main/java/io/jenetics/jpx/Bounds.java | 4 +--- jpx/src/main/java/io/jenetics/jpx/Copyright.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/DGPSStation.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/Email.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/GPX.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/Length.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/Link.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/Metadata.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/NonNullList.java | 2 +- jpx/src/main/java/io/jenetics/jpx/Person.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/Route.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/Speed.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/Track.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/TrackSegment.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/UInt.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/WayPoint.java | 3 +-- jpx/src/main/java/io/jenetics/jpx/format/Location.java | 3 +-- 17 files changed, 17 insertions(+), 34 deletions(-) diff --git a/jpx/src/main/java/io/jenetics/jpx/Bounds.java b/jpx/src/main/java/io/jenetics/jpx/Bounds.java index 1c811ea0..aceb8f0c 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Bounds.java +++ b/jpx/src/main/java/io/jenetics/jpx/Bounds.java @@ -117,8 +117,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Bounds bounds && + return obj instanceof Bounds bounds && Objects.equals(bounds._minLatitude, _minLatitude) && Objects.equals(bounds._minLongitude, _minLongitude) && Objects.equals(bounds._maxLatitude, _maxLatitude) && @@ -140,7 +139,6 @@ public String toString() { * Return a collector which calculates the bounds of a given way-point * stream. The following example shows how to calculate the bounds of all * track-points of a given GPX object. - * * {@snippet lang="java": * final Bounds bounds = gpx.tracks() * .flatMap(Track::segments) diff --git a/jpx/src/main/java/io/jenetics/jpx/Copyright.java b/jpx/src/main/java/io/jenetics/jpx/Copyright.java index 4ef80af9..8ea7d4c0 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Copyright.java +++ b/jpx/src/main/java/io/jenetics/jpx/Copyright.java @@ -103,8 +103,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Copyright cr && + return obj instanceof Copyright cr && Objects.equals(cr._author, _author) && Objects.equals(cr._year, _year) && Objects.equals(cr._license, _license); diff --git a/jpx/src/main/java/io/jenetics/jpx/DGPSStation.java b/jpx/src/main/java/io/jenetics/jpx/DGPSStation.java index 1637a907..03b53dd2 100644 --- a/jpx/src/main/java/io/jenetics/jpx/DGPSStation.java +++ b/jpx/src/main/java/io/jenetics/jpx/DGPSStation.java @@ -120,8 +120,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof DGPSStation dgps && + return obj instanceof DGPSStation dgps && dgps._value == _value; } diff --git a/jpx/src/main/java/io/jenetics/jpx/Email.java b/jpx/src/main/java/io/jenetics/jpx/Email.java index d30b4cf1..034ebf66 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Email.java +++ b/jpx/src/main/java/io/jenetics/jpx/Email.java @@ -105,8 +105,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Email email && + return obj instanceof Email email && Objects.equals(email._id, _id) && Objects.equals(email._domain, _domain); } diff --git a/jpx/src/main/java/io/jenetics/jpx/GPX.java b/jpx/src/main/java/io/jenetics/jpx/GPX.java index ec41e9ab..cf97c45c 100644 --- a/jpx/src/main/java/io/jenetics/jpx/GPX.java +++ b/jpx/src/main/java/io/jenetics/jpx/GPX.java @@ -472,8 +472,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof GPX gpx && + return obj instanceof GPX gpx && Objects.equals(gpx._creator, _creator) && Objects.equals(gpx._version, _version) && Objects.equals(gpx._metadata, _metadata) && diff --git a/jpx/src/main/java/io/jenetics/jpx/Length.java b/jpx/src/main/java/io/jenetics/jpx/Length.java index c9c9bef4..9a702ba7 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Length.java +++ b/jpx/src/main/java/io/jenetics/jpx/Length.java @@ -192,8 +192,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Length lng && + return obj instanceof Length lng && Double.compare(lng._value, _value) == 0; } diff --git a/jpx/src/main/java/io/jenetics/jpx/Link.java b/jpx/src/main/java/io/jenetics/jpx/Link.java index 06c2c3e6..fbe9d637 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Link.java +++ b/jpx/src/main/java/io/jenetics/jpx/Link.java @@ -101,8 +101,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Link link && + return obj instanceof Link link && Objects.equals(link._href, _href) && Objects.equals(link._text, _text) && Objects.equals(link._type, _type); diff --git a/jpx/src/main/java/io/jenetics/jpx/Metadata.java b/jpx/src/main/java/io/jenetics/jpx/Metadata.java index 15d098c4..451d37d7 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Metadata.java +++ b/jpx/src/main/java/io/jenetics/jpx/Metadata.java @@ -270,8 +270,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Metadata meta && + return obj instanceof Metadata meta && Objects.equals(meta._name, _name) && Objects.equals(meta._description, _description) && Objects.equals(meta._author, _author) && diff --git a/jpx/src/main/java/io/jenetics/jpx/NonNullList.java b/jpx/src/main/java/io/jenetics/jpx/NonNullList.java index 7b328e51..d3254d9b 100644 --- a/jpx/src/main/java/io/jenetics/jpx/NonNullList.java +++ b/jpx/src/main/java/io/jenetics/jpx/NonNullList.java @@ -292,7 +292,7 @@ public int hashCode() { @Override public boolean equals(final Object o) { - return o == this || _adoptee.equals(o); + return o instanceof List list && _adoptee.equals(list); } } diff --git a/jpx/src/main/java/io/jenetics/jpx/Person.java b/jpx/src/main/java/io/jenetics/jpx/Person.java index 257739f0..fc8b8ba2 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Person.java +++ b/jpx/src/main/java/io/jenetics/jpx/Person.java @@ -116,8 +116,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Person person && + return obj instanceof Person person && Objects.equals(person._name, _name) && Objects.equals(person._email, _email) && Objects.equals(person._link, _link); diff --git a/jpx/src/main/java/io/jenetics/jpx/Route.java b/jpx/src/main/java/io/jenetics/jpx/Route.java index dff2df36..e33fb3bc 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Route.java +++ b/jpx/src/main/java/io/jenetics/jpx/Route.java @@ -288,8 +288,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Route route && + return obj instanceof Route route && Objects.equals(route._name, _name) && Objects.equals(route._comment, _comment) && Objects.equals(route._description, _description) && diff --git a/jpx/src/main/java/io/jenetics/jpx/Speed.java b/jpx/src/main/java/io/jenetics/jpx/Speed.java index 186102a6..6bb03f25 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Speed.java +++ b/jpx/src/main/java/io/jenetics/jpx/Speed.java @@ -167,8 +167,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Speed speed && + return obj instanceof Speed speed && Double.compare(speed._value, _value) == 0; } diff --git a/jpx/src/main/java/io/jenetics/jpx/Track.java b/jpx/src/main/java/io/jenetics/jpx/Track.java index 613a0136..7352ae03 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Track.java +++ b/jpx/src/main/java/io/jenetics/jpx/Track.java @@ -296,8 +296,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof Track track && + return obj instanceof Track track && Objects.equals(track._name, _name) && Objects.equals(track._comment, _comment) && Objects.equals(track._description, _description) && diff --git a/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java b/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java index ce12f479..2e950c8f 100644 --- a/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java +++ b/jpx/src/main/java/io/jenetics/jpx/TrackSegment.java @@ -164,8 +164,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof TrackSegment && + return obj instanceof TrackSegment && Objects.equals(((TrackSegment)obj)._points, _points); } diff --git a/jpx/src/main/java/io/jenetics/jpx/UInt.java b/jpx/src/main/java/io/jenetics/jpx/UInt.java index 2a3ddc1b..c3961a6f 100644 --- a/jpx/src/main/java/io/jenetics/jpx/UInt.java +++ b/jpx/src/main/java/io/jenetics/jpx/UInt.java @@ -105,8 +105,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof UInt uint && + return obj instanceof UInt uint && uint._value == _value; } diff --git a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java index ac4a8218..3e5ec462 100644 --- a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java +++ b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java @@ -467,8 +467,7 @@ public int hashCode() { @Override public boolean equals(final Object obj) { - return obj == this || - obj instanceof WayPoint wp && + return obj instanceof WayPoint wp && Objects.equals(wp._latitude, _latitude) && Objects.equals(wp._longitude, _longitude) && Objects.equals(wp._elevation, _elevation) && diff --git a/jpx/src/main/java/io/jenetics/jpx/format/Location.java b/jpx/src/main/java/io/jenetics/jpx/format/Location.java index db30c627..5b042c9d 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Location.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Location.java @@ -108,8 +108,7 @@ public int hashCode(){ @Override public boolean equals(final Object other) { - return other == this || - other instanceof Location loc && + return other instanceof Location loc && Objects.equals(_latitude, loc._latitude) && Objects.equals(_longitude, loc._longitude) && Objects.equals(_elevation, loc._elevation); From d3197cbd09a138c0810a05f553ce9463b02ce060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 20:27:54 +0100 Subject: [PATCH 22/26] #192: Some code cleanup. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- jpx/src/main/java/io/jenetics/jpx/Filters.java | 4 ++-- jpx/src/main/java/io/jenetics/jpx/Route.java | 4 ++-- jpx/src/main/java/io/jenetics/jpx/Speed.java | 1 - jpx/src/main/java/io/jenetics/jpx/Track.java | 4 ++-- jpx/src/main/java/io/jenetics/jpx/WayPoint.java | 4 ++-- jpx/src/main/java/io/jenetics/jpx/XMLReader.java | 1 - jpx/src/main/java/io/jenetics/jpx/XMLWriter.java | 1 - 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/jpx/src/main/java/io/jenetics/jpx/Filters.java b/jpx/src/main/java/io/jenetics/jpx/Filters.java index bdb83835..6acf7085 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Filters.java +++ b/jpx/src/main/java/io/jenetics/jpx/Filters.java @@ -93,7 +93,7 @@ public static List mergeTracks(final List tracks) { return tracks.isEmpty() ? List.of() : List.of( - tracks.get(0).toBuilder() + tracks.getFirst().toBuilder() .segments(segments) .build() ); @@ -125,7 +125,7 @@ public static List fullyMergeTracks(final List tracks) { return tracks.isEmpty() ? List.of() : List.of( - tracks.get(0).toBuilder() + tracks.getFirst().toBuilder() .segments(List.of(TrackSegment.of(points))) .build() ); diff --git a/jpx/src/main/java/io/jenetics/jpx/Route.java b/jpx/src/main/java/io/jenetics/jpx/Route.java index e33fb3bc..eca0fedb 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Route.java +++ b/jpx/src/main/java/io/jenetics/jpx/Route.java @@ -861,13 +861,13 @@ static Route read(final DataInput in) throws IOException { private static String url(final Route route) { return route.getLinks().isEmpty() ? null - : route.getLinks().get(0).getHref().toString(); + : route.getLinks().getFirst().getHref().toString(); } private static String urlname(final Route route) { return route.getLinks().isEmpty() ? null - : route.getLinks().get(0).getText().orElse(null); + : route.getLinks().getFirst().getText().orElse(null); } // Define the necessary writers for the different versions. diff --git a/jpx/src/main/java/io/jenetics/jpx/Speed.java b/jpx/src/main/java/io/jenetics/jpx/Speed.java index 6bb03f25..bd1c5f09 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Speed.java +++ b/jpx/src/main/java/io/jenetics/jpx/Speed.java @@ -88,7 +88,6 @@ public enum Unit { * Convert the given speed value of the given {@code sourceUnit} into a * speed value of {@code this} speed unit. The given example converts 3 * knots into kilometers per hour. - * * {@snippet lang="java": * final double kilometersPerHour = KILOMETERS_PER_HOUR.convert(3, KNOTS); * } diff --git a/jpx/src/main/java/io/jenetics/jpx/Track.java b/jpx/src/main/java/io/jenetics/jpx/Track.java index 7352ae03..2053579b 100644 --- a/jpx/src/main/java/io/jenetics/jpx/Track.java +++ b/jpx/src/main/java/io/jenetics/jpx/Track.java @@ -839,13 +839,13 @@ static Track read(final DataInput in) throws IOException { private static String url(final Track track) { return track.getLinks().isEmpty() ? null - : track.getLinks().get(0).getHref().toString(); + : track.getLinks().getFirst().getHref().toString(); } private static String urlname(final Track track) { return track.getLinks().isEmpty() ? null - : track.getLinks().get(0).getText().orElse(null); + : track.getLinks().getFirst().getText().orElse(null); } // Define the necessary writers for the different versions. diff --git a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java index 3e5ec462..28912f5c 100644 --- a/jpx/src/main/java/io/jenetics/jpx/WayPoint.java +++ b/jpx/src/main/java/io/jenetics/jpx/WayPoint.java @@ -1945,13 +1945,13 @@ static WayPoint read(final DataInput in) throws IOException { private static String url(final WayPoint point) { return point.getLinks().isEmpty() ? null - : point.getLinks().get(0).getHref().toString(); + : point.getLinks().getFirst().getHref().toString(); } private static String urlname(final WayPoint point) { return point.getLinks().isEmpty() ? null - : point.getLinks().get(0).getText().orElse(null); + : point.getLinks().getFirst().getText().orElse(null); } // Define the necessary writers for the different versions. diff --git a/jpx/src/main/java/io/jenetics/jpx/XMLReader.java b/jpx/src/main/java/io/jenetics/jpx/XMLReader.java index a4cd4448..e72936b2 100644 --- a/jpx/src/main/java/io/jenetics/jpx/XMLReader.java +++ b/jpx/src/main/java/io/jenetics/jpx/XMLReader.java @@ -99,7 +99,6 @@ enum Type { /** * Read the given type from the underlying XML stream {@code reader}. - * * {@snippet lang="java": * try (AutoCloseableXMLStreamReader xml = XML.reader(in)) { * // Move XML stream to first element. diff --git a/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java b/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java index 679e4161..d6af4e1d 100644 --- a/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java +++ b/jpx/src/main/java/io/jenetics/jpx/XMLWriter.java @@ -109,7 +109,6 @@ void write(final XMLStreamWriter xml, final T data) /** * Writes the attribute with the given {@code name} to the current * outer element. - * * {@snippet lang="java": * final XMLWriter writer1 = elem("element", attr("attribute")); * } From 5c86a55bcd88de3082d47a627b4083a079fa4145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 20:28:57 +0100 Subject: [PATCH 23/26] #192: Update version number. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- buildSrc/src/main/kotlin/Env.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Env.kt b/buildSrc/src/main/kotlin/Env.kt index 78f339f9..a6994cdb 100644 --- a/buildSrc/src/main/kotlin/Env.kt +++ b/buildSrc/src/main/kotlin/Env.kt @@ -52,7 +52,7 @@ object Env { * Information about the library and author. */ object JPX { - const val VERSION = "4.0.0-SNAPSHOT" + const val VERSION = "4.0.0" const val ID = "jpx" const val NAME = "jpx" const val GROUP = "io.jenetics" From 575efd2a595c9304b360acad07804c54324703cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 20:34:20 +0100 Subject: [PATCH 24/26] #192: Update README. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- README.md | 54 ++++++------------------------------------------------ 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index a0b9839f..e5af928f 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,18 @@ # JPX ![Build Status](https://github.com/jenetics/jpx/actions/workflows/gradle.yml/badge.svg) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.jenetics/jpx/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jpx%22) +[![Maven Central Version](https://img.shields.io/maven-central/v/io.jenetics/jpx?color=green)](https://central.sonatype.com/artifact/io.jenetics/jpx) [![Javadoc](https://www.javadoc.io/badge/io.jenetics/jpx.svg)](http://www.javadoc.io/doc/io.jenetics/jpx) -**JPX** is a Java library for creating, reading and writing [GPS](https://en.wikipedia.org/wiki/Global_Positioning_System) data in [GPX](https://en.wikipedia.org/wiki/GPS_Exchange_Format) format. It is a *full* implementation of version [1.1](http://www.topografix.com/GPX/1/1/) and version [1.0](http://www.topografix.com/gpx_manual.asp) of the GPX format. The data classes are completely immutable and allows a functional programming style. They are working also nicely with the Java [Stream](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/Stream.html) API. It is also possible to convert the location information into strings which are compatible to the [ISO 6709](http://en.wikipedia.org/wiki/ISO_6709) standard. + +**JPX** is a Java library for creating, reading and writing [GPS](https://en.wikipedia.org/wiki/Global_Positioning_System) data in [GPX](https://en.wikipedia.org/wiki/GPS_Exchange_Format) format. It is a *full* implementation of version [1.1](http://www.topografix.com/GPX/1/1/) and version [1.0](http://www.topografix.com/gpx_manual.asp) of the GPX format. The data classes are completely immutable and allows a functional programming style. They are working also nicely with the Java [Stream](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/stream/Stream.html) API. It is also possible to convert the location information into strings which are compatible to the [ISO 6709](http://en.wikipedia.org/wiki/ISO_6709) standard. Besides the basic functionality of reading and writing GPX files, the library also allows manipulating the read GPX object in a functional way. ## Dependencies -The _JPX_ library needs no external dependencies. It only needs **Java 17** to compile and run. It also runs and compiles with **Java 21** and **Java 23**. +The _JPX_ library needs no external dependencies. It needs **Java 25** to compile and run. ## Building JPX @@ -314,7 +315,7 @@ org.acme.NonValidatingDocumentBuilder The library is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). - Copyright 2016-2025 Franz Wilhelmstötter + Copyright 2016-2026 Franz Wilhelmstötter Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -330,7 +331,7 @@ The library is licensed under the [Apache License, Version 2.0](http://www.apach ## Release notes -### [3.2.1](https://github.com/jenetics/jpx/releases/tag/v3.2.1) +### [4.0.0](https://github.com/jenetics/jpx/releases/tag/v4.0.0) #### Improvements @@ -345,47 +346,4 @@ The library is licensed under the [Apache License, Version 2.0](http://www.apach ### [3.1.0](https://github.com/jenetics/jpx/releases/tag/v3.1.0) -#### Improvements - -* [#170](https://github.com/jenetics/jpx/issues/170): GPX files with invalid version number are now readable in _LENIENT_ mode. -```java -final GPX gpx; -try (InputStream in = new FileInputStream(resource)) { - gpx = GPX.Reader.of(Mode.LENIENT).read(in); -} -``` - -#### Bugs - -* [#167](https://github.com/jenetics/jpx/issues/167): Fixing a test case for Windows. - -### [3.0.1](https://github.com/jenetics/jpx/releases/tag/v3.0.1) - -#### Bugs - -* [#162](https://github.com/jenetics/jpx/issues/162): Elevation serialization for values > 1000m is incompatible with deserialization. - -### [3.0.0](https://github.com/jenetics/jpx/releases/tag/v3.0.0) - -#### Improvements - -* [#125](https://github.com/jenetics/jpx/issues/125): **Breaking change** - Use `Instant` instead of `ZonedDateTime` for `Point.time` property. -* [#148](https://github.com/jenetics/jpx/issues/148): **Breaking change** - Update to Java17. -* [#155](https://github.com/jenetics/jpx/issues/155): Improved `GPX.Reader` and `GPX.Writer` classes. -* [#158](https://github.com/jenetics/jpx/issues/158): Add XML `Document` reader/writer methods. -```java -final GPX gpx = ...; - -final Document doc = XMLProvider.provider() - .documentBuilderFactory() - .newDocumentBuilder() - .newDocument(); - -// The GPX data are written to the empty `doc` object. -GPX.Writer.DEFAULT.write(gpx, new DOMResult(doc)); -``` - -#### Bugs -* [#151](https://github.com/jenetics/jpx/issues/151): `Double`'s being written as exponents in GPX file. -* [#152](https://github.com/jenetics/jpx/issues/152): `LocationFormatter::parse` method is not thread-safe. From e1abab3e5567de30bebfc88b5535a7dea228c648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 20:37:16 +0100 Subject: [PATCH 25/26] #192: Update GitHub Actions for Gradle build process --- .github/workflows/gradle.yml | 49 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 8e26b458..79bd3992 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -1,30 +1,31 @@ name: JPX Build on: - push: - branches: - - master - - releases/* - - issues/* - pull_request: - branches: - - master - - releases/* + push: + branches: + - master + - releases/* + - issues/* + pull_request: + branches: + - master + - releases/* jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ ubuntu-latest, macos-latest ] - java-version: [ 21, 24 ] - steps: - - uses: actions/checkout@v2 + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest, macos-latest ] + java-version: [ 25 ] + steps: + - uses: actions/checkout@v4 - - name: Set up JDK ${{ matrix.java-version }} on ${{ matrix.os }} - uses: actions/setup-java@v2 - with: - java-version: ${{ matrix.java-version }} - distribution: 'zulu' - - name: Build with Gradle - run: ./gradlew build --stacktrace --info + - name: Set up JDK ${{ matrix.java-version }} on ${{ matrix.os }} + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java-version }} + distribution: 'zulu' + cache: 'gradle' + - name: Build with Gradle + run: ./gradlew build --stacktrace --info From 88309a2d1e0bc286428d9778f9d88d596dd5bdb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20Wilhelmst=C3=B6tter?= Date: Sun, 22 Feb 2026 20:43:44 +0100 Subject: [PATCH 26/26] Update README. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Franz Wilhelmstötter --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e5af928f..8bf2dc9a 100644 --- a/README.md +++ b/README.md @@ -335,15 +335,8 @@ The library is licensed under the [Apache License, Version 2.0](http://www.apach #### Improvements -* [#186](https://github.com/jenetics/jpx/issues/186): LENIENT mode allows GPX tags without creator attributes. +* [#177](https://github.com/jenetics/jpx/issues/177): Convert 'geom' classes to records. +* [#192](https://github.com/jenetics/jpx/issues/192): Update library to Java 25. -### [3.2.0](https://github.com/jenetics/jpx/releases/tag/v3.2.0) - -#### Improvements - -* [#183](https://github.com/jenetics/jpx/issues/183): Update Gradle to 8.11 and improve build scripts. -* [#181](https://github.com/jenetics/jpx/pull/181): Update code examples in README. - -### [3.1.0](https://github.com/jenetics/jpx/releases/tag/v3.1.0)