Skip to content

Commit

Permalink
chore: move to Java 21 (#27)
Browse files Browse the repository at this point in the history
Uses new Java 17 branch of solarpositioning.

Considered experimental for now.
  • Loading branch information
klausbrunner authored Oct 23, 2023
1 parent 9438290 commit 7c01744
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 113 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/env.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
JAVA_VERSION=17
JAVA_VERSION=21
GRAAL_DISTRO=graalvm
2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Status: _beta_. Current functionality works, but needs more user testing and pol

## Requirements and installation

Solarpos is a Java application, requiring Java 17 or newer. See the [latest release](https://github.com/klausbrunner/solarpos/releases/latest) or build from source using `mvn package`.
Solarpos is a Java application, requiring Java 21 or newer. See the [latest release](https://github.com/klausbrunner/solarpos/releases/latest) or build from source using `mvn package`.

### Native builds

Expand Down
15 changes: 8 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

<groupId>net.e175.klaus</groupId>
<artifactId>solarpos</artifactId>
<version>0.3.7-SNAPSHOT</version>

<version>0.4.0-SNAPSHOT</version>
<parent>
<groupId>org.basepom</groupId>
<artifactId>basepom-minimal</artifactId>
<version>55</version>
<version>56</version>
</parent>

<name>solarpos</name>
Expand All @@ -34,14 +33,16 @@

<properties>
<basepom.main-class>net.e175.klaus.solarpos.Main</basepom.main-class>
<project.build.targetJdk>17</project.build.targetJdk>
<project.build.targetJdk>21</project.build.targetJdk>
<picocli.version>4.7.5</picocli.version>

<scmCommentPrefix>build: [maven-release-plugin] [skip ci]</scmCommentPrefix>
<basepom.release.tag-name-format>v@{project.version}</basepom.release.tag-name-format>

<basepom.check.skip-dependency>true</basepom.check.skip-dependency>
<basepom.check.skip-checkstyle>true</basepom.check.skip-checkstyle>
<basepom.check.skip-spotbugs>true</basepom.check.skip-spotbugs> <!-- temporary until it works with Java 21 -->
<basepom.check.skip-pmd>true</basepom.check.skip-pmd> <!-- temporary until it works with Java 21 -->
</properties>

<scm>
Expand Down Expand Up @@ -167,9 +168,9 @@
<packagers>
<brew>
<active>RELEASE</active>
<tap>
<repository>
<name>homebrew-tap</name>
</tap>
</repository>
<extraProperties>
<useVersionedJava>false</useVersionedJava>
</extraProperties>
Expand All @@ -191,7 +192,7 @@
<dependency>
<groupId>net.e175.klaus</groupId>
<artifactId>solarpositioning</artifactId>
<version>0.1.10</version>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
Expand Down
37 changes: 15 additions & 22 deletions src/main/java/net/e175/klaus/solarpos/PositionCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.stream.Stream;
import net.e175.klaus.solarpositioning.AzimuthZenithAngle;
import net.e175.klaus.solarpositioning.Grena3;
import net.e175.klaus.solarpositioning.SPA;
import net.e175.klaus.solarpositioning.SolarPosition;
import picocli.CommandLine;

@CommandLine.Command(name = "position", description = "Calculates topocentric solar coordinates.")
Expand Down Expand Up @@ -71,7 +71,7 @@ public Integer call() {
dateTimes.forEach(
dateTime -> {
final double deltaT = parent.getBestGuessDeltaT(dateTime);
AzimuthZenithAngle position =
SolarPosition position =
switch (this.algorithm) {
case SPA -> SPA.calculateSolarPosition(
dateTime,
Expand All @@ -96,38 +96,31 @@ static Stream<ZonedDateTime> getDatetimes(
TemporalAccessor dateTime, Optional<ZoneId> zoneId, int step) {
final ZoneId overrideTz = zoneId.orElse(ZoneId.systemDefault());

if (dateTime instanceof Year y) {
return Stream.iterate(
return switch (dateTime) {
case Year y -> Stream.iterate(
ZonedDateTime.of(LocalDate.of(y.getValue(), 1, 1), LocalTime.of(0, 0), overrideTz),
i -> i.getYear() == y.getValue(),
i -> i.plusSeconds(step));
} else if (dateTime instanceof YearMonth ym) {
return Stream.iterate(
case YearMonth ym -> Stream.iterate(
ZonedDateTime.of(
LocalDate.of(ym.getYear(), ym.getMonth(), 1), LocalTime.of(0, 0), overrideTz),
i -> i.getMonth() == ym.getMonth(),
i -> i.plusSeconds(step));
} else if (dateTime instanceof LocalDate ld) {
return Stream.iterate(
case LocalDate ld -> Stream.iterate(
ZonedDateTime.of(ld, LocalTime.of(0, 0), overrideTz),
i -> i.getDayOfMonth() == ld.getDayOfMonth(),
i -> i.plusSeconds(step));
} else if (dateTime instanceof LocalDateTime ldt) {
return Stream.of(ZonedDateTime.of(ldt, overrideTz));
} else if (dateTime instanceof LocalTime lt) {
return Stream.of(ZonedDateTime.of(LocalDate.now(), lt, overrideTz));
} else if (dateTime instanceof OffsetTime ot) {
return Stream.of(
case LocalDateTime ldt -> Stream.of(ZonedDateTime.of(ldt, overrideTz));
case LocalTime lt -> Stream.of(ZonedDateTime.of(LocalDate.now(), lt, overrideTz));
case OffsetTime ot -> Stream.of(
ZonedDateTime.of(
LocalDate.now(), ot.toLocalTime(), zoneId.isPresent() ? overrideTz : ot.getOffset()));
} else if (dateTime instanceof ZonedDateTime zdt) {
return Stream.of(
case ZonedDateTime zdt -> Stream.of(
zoneId.isPresent()
? ZonedDateTime.of(zdt.toLocalDate(), zdt.toLocalTime(), overrideTz)
: zdt);
} else {
throw new IllegalStateException("unexpected date/time type " + dateTime);
}
default -> throw new IllegalStateException("unexpected date/time type " + dateTime);
};
}

private static final Map<Boolean, String> JSON_FORMATS =
Expand Down Expand Up @@ -183,7 +176,7 @@ private String buildOutput(
Main.Format format,
ZonedDateTime dateTime,
double deltaT,
AzimuthZenithAngle result,
SolarPosition result,
boolean showInput) {
String template = TEMPLATES.get(format).get(showInput);
DateTimeFormatter dtf =
Expand All @@ -198,7 +191,7 @@ private String buildOutput(
temperature,
dtf.format(dateTime),
deltaT,
result.getAzimuth(),
result.getZenithAngle());
result.azimuth(),
result.zenithAngle());
}
}
94 changes: 55 additions & 39 deletions src/main/java/net/e175/klaus/solarpos/SunriseCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.concurrent.Callable;
import java.util.stream.Stream;
import net.e175.klaus.solarpositioning.SPA;
import net.e175.klaus.solarpositioning.SunriseTransitSet;
import net.e175.klaus.solarpositioning.SunriseResult;
import picocli.CommandLine;

@CommandLine.Command(
Expand Down Expand Up @@ -47,7 +47,7 @@ public Integer call() {
dateTimes.forEach(
dateTime -> {
final double deltaT = parent.getBestGuessDeltaT(dateTime);
Map<SPA.Horizon, SunriseTransitSet> result =
Map<SPA.Horizon, SunriseResult> result =
SPA.calculateSunriseTransitSet(
dateTime, parent.latitude, parent.longitude, deltaT, horizons);
out.print(
Expand All @@ -69,36 +69,29 @@ public Integer call() {
static Stream<ZonedDateTime> getDatetimes(TemporalAccessor dateTime, Optional<ZoneId> zoneId) {
final ZoneId overrideTz = zoneId.orElse(ZoneId.systemDefault());

if (dateTime instanceof Year y) {
return Stream.iterate(
return switch (dateTime) {
case Year y -> Stream.iterate(
ZonedDateTime.of(
LocalDate.of(y.getValue(), Month.JANUARY, 1), LocalTime.of(0, 0), overrideTz),
i -> i.getYear() == y.getValue(),
i -> i.plusDays(1));
} else if (dateTime instanceof YearMonth ym) {
return Stream.iterate(
case YearMonth ym -> Stream.iterate(
ZonedDateTime.of(
LocalDate.of(ym.getYear(), ym.getMonth(), 1), LocalTime.of(0, 0), overrideTz),
i -> i.getMonth() == ym.getMonth(),
i -> i.plusDays(1));
} else if (dateTime instanceof LocalDate ld) {
return Stream.of(ZonedDateTime.of(ld, LocalTime.of(0, 0), overrideTz));
} else if (dateTime instanceof LocalDateTime ldt) {
return Stream.of(ZonedDateTime.of(ldt, overrideTz));
} else if (dateTime instanceof LocalTime lt) {
return Stream.of(ZonedDateTime.of(LocalDate.now(), lt, overrideTz));
} else if (dateTime instanceof OffsetTime ot) {
return Stream.of(
case LocalDate ld -> Stream.of(ZonedDateTime.of(ld, LocalTime.of(0, 0), overrideTz));
case LocalDateTime ldt -> Stream.of(ZonedDateTime.of(ldt, overrideTz));
case LocalTime lt -> Stream.of(ZonedDateTime.of(LocalDate.now(), lt, overrideTz));
case OffsetTime ot -> Stream.of(
ZonedDateTime.of(
LocalDate.now(), ot.toLocalTime(), zoneId.isPresent() ? overrideTz : ot.getOffset()));
} else if (dateTime instanceof ZonedDateTime zdt) {
return Stream.of(
case ZonedDateTime zdt -> Stream.of(
zoneId.isPresent()
? ZonedDateTime.of(zdt.toLocalDate(), zdt.toLocalTime(), overrideTz)
: zdt);
} else {
throw new IllegalStateException("unexpected date/time type " + dateTime);
}
default -> throw new IllegalStateException("unexpected date/time type " + dateTime);
};
}

private static final Map<Main.Format, Map<Boolean, String>> HEADERS =
Expand Down Expand Up @@ -126,7 +119,7 @@ private static String buildOutput(
double longitude,
ZonedDateTime dateTime,
double deltaT,
Map<SPA.Horizon, SunriseTransitSet> result,
Map<SPA.Horizon, SunriseResult> result,
boolean showInput,
boolean twilight) {

Expand Down Expand Up @@ -211,26 +204,53 @@ private static String buildOutput(
}

private static String twilightFragment(
Main.Format format, Map<SPA.Horizon, SunriseTransitSet> result, String pattern) {
final var civil = result.get(SPA.Horizon.CIVIL_TWILIGHT);
final var nautical = result.get(SPA.Horizon.NAUTICAL_TWILIGHT);
final var astronomical = result.get(SPA.Horizon.ASTRONOMICAL_TWILIGHT);
Main.Format format, Map<SPA.Horizon, SunriseResult> result, String pattern) {
final var civil = FormattedSunriseResult.of(format, result.get(SPA.Horizon.CIVIL_TWILIGHT));
final var nautical =
FormattedSunriseResult.of(format, result.get(SPA.Horizon.NAUTICAL_TWILIGHT));
final var astronomical =
FormattedSunriseResult.of(format, result.get(SPA.Horizon.ASTRONOMICAL_TWILIGHT));
return pattern.formatted(
formatDate(format, civil.getSunrise()),
formatDate(format, civil.getSunset()),
formatDate(format, nautical.getSunrise()),
formatDate(format, nautical.getSunset()),
formatDate(format, astronomical.getSunrise()),
formatDate(format, astronomical.getSunset()));
civil.sunrise(),
civil.sunset(),
nautical.sunrise(),
nautical.sunset(),
astronomical.sunrise(),
astronomical.sunset());
}

private static String sunriseSunsetFragment(
Main.Format format, SunriseTransitSet sunriseSunset, String pattern) {
Main.Format format, SunriseResult sunriseSunset, String pattern) {
var formatted = FormattedSunriseResult.of(format, sunriseSunset);

return pattern.formatted(
formatType(format, sunriseSunset.getType()),
formatDate(format, sunriseSunset.getSunrise()),
formatDate(format, sunriseSunset.getTransit()),
formatDate(format, sunriseSunset.getSunset()));
formatted.type(), formatted.sunrise(), formatted.transit(), formatted.sunset());
}

record FormattedSunriseResult(String sunrise, String transit, String sunset, String type) {
private FormattedSunriseResult(
Main.Format format,
TemporalAccessor sunrise,
TemporalAccessor transit,
TemporalAccessor sunset,
String type) {
this(
formatDate(format, sunrise),
formatDate(format, transit),
formatDate(format, sunset),
type);
}

public static FormattedSunriseResult of(Main.Format format, SunriseResult result) {
return switch (result) {
case SunriseResult.AllDay ad -> new FormattedSunriseResult(
format, null, ad.transit(), null, format == HUMAN ? "all day" : "ALL_DAY");
case SunriseResult.AllNight an -> new FormattedSunriseResult(
format, null, an.transit(), null, format == HUMAN ? "all night" : "ALL_NIGHT");
case SunriseResult.RegularDay rd -> new FormattedSunriseResult(
format, rd.sunrise(), rd.transit(), rd.sunset(), format == HUMAN ? "normal" : "NORMAL");
};
}
}

private static String formatDate(Main.Format format, TemporalAccessor temporal) {
Expand All @@ -245,8 +265,4 @@ private static String formatDate(Main.Format format, TemporalAccessor temporal)

return format == JSON ? '"' + dtf.format(temporal) + '"' : dtf.format(temporal);
}

private static Object formatType(Main.Format format, SunriseTransitSet.Type type) {
return format == HUMAN ? type.toString().toLowerCase().replace('_', ' ') : type;
}
}
12 changes: 6 additions & 6 deletions src/test/java/net/e175/klaus/solarpos/MainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,31 +51,31 @@ void dateParsing() {

@Test
void version() {
var result = TestUtil.executeIt("-V");
var result = TestUtil.run("-V");
assertEquals(0, result.returnCode());
assertTrue(result.output().contains("solarpos"));
}

@Test
void rejectsBadDates() {
var result = TestUtil.executeIt("25", "50", "20", "position");
var result = TestUtil.run("25", "50", "20", "position");
assertNotEquals(0, result.returnCode());

result = TestUtil.executeIt("25", "50", "99999", "position");
result = TestUtil.run("25", "50", "99999", "position");
assertNotEquals(0, result.returnCode());

result = TestUtil.executeIt("25", "50", "2024-12-32", "position");
result = TestUtil.run("25", "50", "2024-12-32", "position");
assertNotEquals(0, result.returnCode());
}

@Test
void rejectsBadCoords() {
var dateTime = "2023";

var result = TestUtil.executeIt("91", "0", dateTime, "position");
var result = TestUtil.run("91", "0", dateTime, "position");
assertNotEquals(0, result.returnCode());

result = TestUtil.executeIt("0", "200", dateTime, "position");
result = TestUtil.run("0", "200", dateTime, "position");
assertNotEquals(0, result.returnCode());
}
}
Loading

0 comments on commit 7c01744

Please sign in to comment.