Split UpdateScheduler functionality into a new ApplicationStartupListener component; relocate configuration classes to model.config package; refine README.md phrasing and structure.
Build and Push Docker Image / build-and-push (push) Successful in 26s

This commit is contained in:
2026-07-12 11:48:21 +02:00
parent 77db44b1f5
commit 11110771a8
9 changed files with 73 additions and 57 deletions
+6 -7
View File
@@ -5,19 +5,18 @@
This project Spring Boot web service that automatically fetches, manages, and serves Javadoc documentation for Maven artifacts. This project Spring Boot web service that automatically fetches, manages, and serves Javadoc documentation for Maven artifacts.
If you encounter any bugs or find missing features, feel free to report them on If you encounter any bugs or find missing features, feel free to report them on
the [Github Issues page](https://github.com/th-schwarz/JavadocViewerService/issues). the [GitHub Issues page](https://github.com/th-schwarz/JavadocViewerService/issues).
## Features ## Features
- Fetches Javadoc JARs from Maven Central or custom Maven repositories - Retrieves Javadoc JARs from Maven Central or custom Maven repositories
- Tracks multiple Maven artifacts with version detection - Tracks multiple Maven artefacts with version detection (only the latest version is taken into account).
- Serves generated Javadoc via a simple Bootstrap web UI - Delivers generated Javadoc content via a simple bootstrap web interface
- Scheduled updates via configurable cron expression - Scheduled updates via a configurable cron expression
- Persists metadata in an embedded H2 database (Liquibase-managed)
## Requirements ## Requirements
JRE-21 or docker At least JRE-21 or docker
## Start ## Start
### ... with Java ### ... with Java
@@ -1,6 +1,6 @@
package codes.thischwa.jdvs.service; package codes.thischwa.jdvs.config;
import codes.thischwa.jdvs.config.JdvsConfig; import codes.thischwa.jdvs.model.config.JdvsConfig;
import codes.thischwa.jdvs.jpa.GitRepositoryRepository; import codes.thischwa.jdvs.jpa.GitRepositoryRepository;
import codes.thischwa.jdvs.model.GitRepository; import codes.thischwa.jdvs.model.GitRepository;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -1,4 +1,4 @@
package codes.thischwa.jdvs.config; package codes.thischwa.jdvs.model.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -1,4 +1,4 @@
package codes.thischwa.jdvs.config; package codes.thischwa.jdvs.model.config;
import java.util.List; import java.util.List;
import lombok.Data; import lombok.Data;
@@ -1,4 +1,4 @@
package codes.thischwa.jdvs.config; package codes.thischwa.jdvs.model.config;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -0,0 +1,58 @@
package codes.thischwa.jdvs.service;
import codes.thischwa.jdvs.config.RepoConfigLoader;
import codes.thischwa.jdvs.jpa.GitRepositoryRepository;
import codes.thischwa.jdvs.model.config.JdvsConfig;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
@Slf4j
public class ApplicationStartupListener {
private final GitRepositoryRepository repository;
private final JdvsConfig jdvsConfig;
private final RepoConfigLoader repoConfigLoader;
private final UpdateScheduler updateScheduler;
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReady() {
if (jdvsConfig.isCleanOnStart()) {
log.info("'jdvs.clean-on-start' is enabled cleaning base directory and database.");
cleanBaseDir();
repository.deleteAll();
}
repoConfigLoader.loadConfig();
if (jdvsConfig.isRunOnStart()) {
log.info("'jdvs.run-on-start' is enabled running initial update.");
updateScheduler.updateAll();
}
}
private void cleanBaseDir() {
Path baseDir = Path.of(jdvsConfig.getBaseDir());
if (!Files.exists(baseDir)) {
return;
}
try (var stream = Files.walk(baseDir)) {
stream.sorted(Comparator.reverseOrder()).forEach(path -> {
try {
Files.delete(path);
} catch (IOException e) {
log.warn("Failed to delete path: {}", path, e);
}
});
log.info("Deleted base directory: {}", baseDir);
} catch (IOException e) {
log.error("Failed to walk base directory: {}", baseDir, e);
}
}
}
@@ -1,7 +1,7 @@
package codes.thischwa.jdvs.service; package codes.thischwa.jdvs.service;
import codes.thischwa.jdvs.config.JdvsConfig; import codes.thischwa.jdvs.model.config.JdvsConfig;
import codes.thischwa.jdvs.config.JdvsConfig.RepoConfig; import codes.thischwa.jdvs.model.config.JdvsConfig.RepoConfig;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
@@ -1,19 +1,12 @@
package codes.thischwa.jdvs.service; package codes.thischwa.jdvs.service;
import codes.thischwa.jdvs.config.JdvsConfig;
import codes.thischwa.jdvs.jpa.GitRepositoryRepository; import codes.thischwa.jdvs.jpa.GitRepositoryRepository;
import codes.thischwa.jdvs.model.GitRepository; import codes.thischwa.jdvs.model.GitRepository;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -21,43 +14,9 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class UpdateScheduler { public class UpdateScheduler {
private final GitRepositoryRepository repository; private final GitRepositoryRepository repository;
private final MavenJavadocService mavenJavadocService; private final MavenJavadocService mavenJavadocService;
private final JdvsConfig jdvsConfig;
private final RepoConfigLoader repoConfigLoader;
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReady() {
if (jdvsConfig.isCleanOnStart()) {
log.info("'jdvs.clean-on-start' is enabled cleaning base directory and database.");
cleanBaseDir();
repository.deleteAll();
}
repoConfigLoader.loadConfig();
if (jdvsConfig.isRunOnStart()) {
log.info("'jdvs.run-on-start' is enabled running initial update.");
updateAll();
}
}
private void cleanBaseDir() {
Path baseDir = Path.of(jdvsConfig.getBaseDir());
if (!Files.exists(baseDir)) {
return;
}
try (var stream = Files.walk(baseDir)) {
stream.sorted(Comparator.reverseOrder()).forEach(path -> {
try {
Files.delete(path);
} catch (IOException e) {
log.warn("Failed to delete path: {}", path, e);
}
});
log.info("Deleted base directory: {}", baseDir);
} catch (IOException e) {
log.error("Failed to walk base directory: {}", baseDir, e);
}
}
@Scheduled(cron = "${jdvs.cron}") @Scheduled(cron = "${jdvs.cron}")
public void updateAll() { public void updateAll() {
@@ -1,6 +1,6 @@
package codes.thischwa.jdvs.web; package codes.thischwa.jdvs.web;
import codes.thischwa.jdvs.config.JdvsConfig; import codes.thischwa.jdvs.model.config.JdvsConfig;
import java.nio.file.Path; import java.nio.file.Path;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;