diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 424b19a5..7c3d4ab1 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, 23 ] + java-version: [ 21, 23 ] steps: - uses: actions/checkout@v2 diff --git a/build.gradle.kts b/build.gradle.kts index 235b2e7f..3a80b5c9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,7 +28,6 @@ import io.jenetics.gradle.dsl.moduleName */ plugins { base - id("me.champeau.jmh") version "0.7.2" apply false } rootProject.version = JPX.VERSION @@ -71,8 +70,8 @@ gradle.projectsEvaluated { plugins.withType { configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } configure { @@ -169,13 +168,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:", @@ -193,38 +191,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 { - providers.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) - } - } - } } /** @@ -242,13 +208,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" 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/buildSrc/src/main/kotlin/Env.kt b/buildSrc/src/main/kotlin/Env.kt index 84cd47b8..78f339f9 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.2.0" + const val VERSION = "4.0.0-SNAPSHOT" const val ID = "jpx" const val NAME = "jpx" const val GROUP = "io.jenetics" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..f1734af3 --- /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.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" diff --git a/jpx/src/main/java/io/jenetics/jpx/Bounds.java b/jpx/src/main/java/io/jenetics/jpx/Bounds.java index d717c078..1c811ea0 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/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 4792a20a..1155cef5 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 reading otherwise invalid GPX files, like - *
{@code
+ * This allows to read otherwise invalid GPX files, like
+ * {@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 * @@ -1623,13 +1623,13 @@ byte[] toByteArray(final GPX gpx) { * {@link WayPoint#getLongitude()}, ... *

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

{@code
+		 * maximal 5 fractional digits.
+		 * {@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 a 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 52cb10c7..c9c9bef4 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 96e696e7..15d098c4 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 67ad122a..dff2df36 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 3c11cf51..613a0136 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 008382ca..ac4a8218 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 @@ -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 @@ -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 * @@ -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(), diff --git a/jpx/src/main/java/io/jenetics/jpx/XMLReader.java b/jpx/src/main/java/io/jenetics/jpx/XMLReader.java index 88877e94..a4cd4448 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 3027a76f..679e4161 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/format/CompositeFormat.java b/jpx/src/main/java/io/jenetics/jpx/format/CompositeFormat.java index 1160e2fe..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,10 +26,10 @@ /** * @author Franz Wilhelmstötter - * @version 2.2 + * @version 4.0 * @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 8217d5f8..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 2.2 + * @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 fb4a4b77..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,10 +34,20 @@ * elevation. * * @author Franz Wilhelmstötter - * @version 3.0 + * @version 4.0 * @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..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,10 +26,19 @@ * Base interface for formatting and parsing a location. * * @author Franz Wilhelmstötter - * @version 2.2 + * @version 4.0 * @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/Location.java b/jpx/src/main/java/io/jenetics/jpx/format/Location.java index 5f0a652f..db30c627 100644 --- a/jpx/src/main/java/io/jenetics/jpx/format/Location.java +++ b/jpx/src/main/java/io/jenetics/jpx/format/Location.java @@ -127,7 +127,7 @@ public String toString() { * Create a new location form the given GPS point. * * @param point the GPS point - * @return a new location forms 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/LocationFormatter.java b/jpx/src/main/java/io/jenetics/jpx/format/LocationFormatter.java index 14779d00..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 -> { } } } 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 4086dce1..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,10 +29,10 @@ * rounded, on the assumption that the fractional part will be represented by * minutes and seconds. * - * @version 2.2 + * @version 4.0 * @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..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,10 +27,10 @@ /** * @author Franz Wilhelmstötter - * @version 2.2 + * @version 4.0 * @since 1.4 */ -class OptionalFormat implements Format { +final class OptionalFormat implements Format { private final Format _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 eeddc3a8..ceecb662 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 4.0 * @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 766779fc..78729fe0 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 4.0 * @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,13 +236,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 @@ -282,13 +264,12 @@ 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. - * - *
{@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 @@ -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/module-info.java b/jpx/src/main/java/module-info.java index b3bce315..3a92d48a 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,22 +63,20 @@
  *         
  *     
  * 
- * }
+ * } * * Reading a GPX file - *
{@code
- * final GPX gpx = GPX.read(Path.of("points.gpx"));
- * }
+ * {@snippet lang="java": + * final GPX gpx = GPX.read("points.xml"); + * } * * Reading erroneous GPX files - *
{@code
- * final GPX gpx = GPX.Reader
- *     .of(GPX.Reader.Mode.LENIENT)
- *     .read(Path.of("points.gpx"));
- * }
+ * {@snippet lang="java": + * final GPX gpx = GPX.Reader.of(GPX.Reader.Mode.LENIENT).read("track.xml"); + * } * - * This allows reading otherwise invalid GPX files, like - *
{@code
+ * This allows to read otherwise invalid GPX files, like
+ * {@snippet lang="java":
  * 
  * 
  *   
@@ -110,10 +108,10 @@
  *     
  *   
  * 
- * }
+ * } * * which is read as (if you write it again) - *
{@code
+ * {@snippet lang="java":
  * 
  * 
  *     
@@ -145,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()
@@ -158,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; diff --git a/settings.gradle.kts b/settings.gradle.kts index 84a4340f..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.26.3") - library("commons-math", "org.apache.commons:commons-math3:3.6.1") - library("equalsverifier", "nl.jqno.equalsverifier:equalsverifier:3.17.1") - library("guava", "com.google.guava:guava:33.3.1-jre") - library("prngine", "io.jenetics:prngine:2.0.0") - library("rxjava", "io.reactivex.rxjava2:rxjava:2.2.21") - library("testng", "org.testng:testng:7.10.2") - } - } -} - rootProject.name = "jpx" // The JPX projects.