|
|
|
|
@ -19,7 +19,11 @@ package org.springframework.boot.info;
@@ -19,7 +19,11 @@ package org.springframework.boot.info;
|
|
|
|
|
import java.time.Instant; |
|
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
|
import java.time.format.DateTimeParseException; |
|
|
|
|
import java.util.Objects; |
|
|
|
|
import java.util.Properties; |
|
|
|
|
import java.util.Set; |
|
|
|
|
import java.util.function.Function; |
|
|
|
|
import java.util.function.Predicate; |
|
|
|
|
|
|
|
|
|
import org.springframework.aot.hint.RuntimeHints; |
|
|
|
|
import org.springframework.aot.hint.RuntimeHintsRegistrar; |
|
|
|
|
@ -35,6 +39,9 @@ import org.springframework.context.annotation.ImportRuntimeHints;
@@ -35,6 +39,9 @@ import org.springframework.context.annotation.ImportRuntimeHints;
|
|
|
|
|
@ImportRuntimeHints(GitPropertiesRuntimeHints.class) |
|
|
|
|
public class GitProperties extends InfoProperties { |
|
|
|
|
|
|
|
|
|
static final Set<Coercer> coercers = Set.of(Coercer.milliseconds(), |
|
|
|
|
Coercer.dateTimePattern("yyyy-MM-dd'T'HH:mm:ssXXX"), Coercer.dateTimePattern("yyyy-MM-dd'T'HH:mm:ssZ")); |
|
|
|
|
|
|
|
|
|
public GitProperties(Properties entries) { |
|
|
|
|
super(processEntries(entries)); |
|
|
|
|
} |
|
|
|
|
@ -97,46 +104,58 @@ public class GitProperties extends InfoProperties {
@@ -97,46 +104,58 @@ public class GitProperties extends InfoProperties {
|
|
|
|
|
private static void coercePropertyToEpoch(Properties properties, String key) { |
|
|
|
|
String value = properties.getProperty(key); |
|
|
|
|
if (value != null) { |
|
|
|
|
properties.setProperty(key, coerceToEpoch(value)); |
|
|
|
|
properties.setProperty(key, |
|
|
|
|
coercers.stream() |
|
|
|
|
.map((coercer) -> coercer.apply(value)) |
|
|
|
|
.filter(Objects::nonNull) |
|
|
|
|
.findFirst() |
|
|
|
|
.orElse(value)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Attempt to convert the specified value to epoch time. Git properties information |
|
|
|
|
* are known to be specified either as epoch time in seconds or using a specific date |
|
|
|
|
* format. |
|
|
|
|
* @param s the value to coerce to |
|
|
|
|
* @return the epoch time in milliseconds or the original value if it couldn't be |
|
|
|
|
* converted |
|
|
|
|
* {@link RuntimeHintsRegistrar} for git properties. |
|
|
|
|
*/ |
|
|
|
|
private static String coerceToEpoch(String s) { |
|
|
|
|
Long epoch = parseEpochSecond(s); |
|
|
|
|
if (epoch != null) { |
|
|
|
|
return String.valueOf(epoch); |
|
|
|
|
} |
|
|
|
|
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"); |
|
|
|
|
try { |
|
|
|
|
return String.valueOf(format.parse(s, Instant::from).toEpochMilli()); |
|
|
|
|
} |
|
|
|
|
catch (DateTimeParseException ex) { |
|
|
|
|
return s; |
|
|
|
|
static class GitPropertiesRuntimeHints implements RuntimeHintsRegistrar { |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void registerHints(RuntimeHints hints, ClassLoader classLoader) { |
|
|
|
|
hints.resources().registerPattern("git.properties"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static Long parseEpochSecond(String s) { |
|
|
|
|
try { |
|
|
|
|
return Long.parseLong(s) * 1000; |
|
|
|
|
} |
|
|
|
|
catch (NumberFormatException ex) { |
|
|
|
|
return null; |
|
|
|
|
/** |
|
|
|
|
* Coercer used to convert a source value to epoch time. |
|
|
|
|
*/ |
|
|
|
|
private record Coercer(Function<String, Long> action, Predicate<RuntimeException> ignoredExceptions) { |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Attempt to convert the specified value to epoch time. |
|
|
|
|
* @param value the value to coerce to |
|
|
|
|
* @return the epoch time in milliseconds or {@code null} |
|
|
|
|
*/ |
|
|
|
|
String apply(String value) { |
|
|
|
|
try { |
|
|
|
|
Long result = this.action.apply(value); |
|
|
|
|
return (result != null) ? String.valueOf(result) : null; |
|
|
|
|
} |
|
|
|
|
catch (RuntimeException ex) { |
|
|
|
|
if (this.ignoredExceptions.test(ex)) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
throw ex; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static class GitPropertiesRuntimeHints implements RuntimeHintsRegistrar { |
|
|
|
|
static Coercer milliseconds() { |
|
|
|
|
return new Coercer((value) -> Long.parseLong(value) * 1000, NumberFormatException.class::isInstance); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void registerHints(RuntimeHints hints, ClassLoader classLoader) { |
|
|
|
|
hints.resources().registerPattern("git.properties"); |
|
|
|
|
static Coercer dateTimePattern(String pattern) { |
|
|
|
|
return new Coercer( |
|
|
|
|
(value) -> DateTimeFormatter.ofPattern(pattern).parse(value, Instant::from).toEpochMilli(), |
|
|
|
|
DateTimeParseException.class::isInstance); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|