Move to java 21 and refactor accordingly

This commit is contained in:
Dmitry Isaenko 2025-05-02 18:25:32 +03:00
parent 97fd90fb5a
commit 79a5a04488
22 changed files with 74 additions and 96 deletions

View file

@ -15,7 +15,7 @@
<name>marinesco</name>
<description>Home library</description>
<properties>
<java.version>17</java.version>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
@ -84,6 +84,7 @@
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>

View file

@ -18,9 +18,9 @@ import ru.redrise.marinesco.settings.ApplicationSettings;
@Slf4j
@Configuration
public class ShinyApplicationRunner {
private UserRepository users;
private RolesRepository roles;
private ApplicationSettings settings;
private final UserRepository users;
private final RolesRepository roles;
private final ApplicationSettings settings;
public ShinyApplicationRunner(UserRepository users, RolesRepository roles, ApplicationSettings settings) {
this.users = users;
@ -57,7 +57,7 @@ public class ShinyApplicationRunner {
List<UserRole> adminRoleOnlyAthority = roles.findByType(UserRole.Type.ADMIN);
if (login == null || login.size() == 0 || password == null || password.size() == 0) {
if (login == null || login.isEmpty() || password == null || password.isEmpty()) {
log.warn("No administrator credentials provided, using defaults:\n * Login: root\n * Password: root\n Expected: --admin_login LOGIN --admin_password PASSWORD "); // TODO: Move into properties i18n
var adminUser = new User("root", encoder.encode("root"), "SuperAdmin", adminRoleOnlyAthority);
users.save(adminUser);

View file

@ -74,8 +74,8 @@ public class User implements UserDetails{
}
public boolean isAdmin(){
for (UserRole athority : authorities){
if (athority.getAuthority().equals("ROLE_ADMIN"))
for (UserRole authority : authorities){
if (authority.getAuthority().equals("ROLE_ADMIN"))
return true;
}
return false;

View file

@ -17,17 +17,17 @@ public class UserGenerified {
private String name;
private String displayName;
private List<UserRole> athorities;
private List<UserRole> athoritiesLost;
private List<UserRole> authorities;
private List<UserRole> authoritiesLost;
private String password;
public UserGenerified(User user, List<UserRole> allRolesList){
this.id = user.getId();
this.name = user.getUsername();
this.displayName = user.getDisplayname();
this.athorities = user.getAuthorities();
this.athoritiesLost = allRolesList.stream()
.filter(element -> !athorities.contains(element))
this.authorities = user.getAuthorities();
this.authoritiesLost = allRolesList.stream()
.filter(element -> !authorities.contains(element))
.collect(Collectors.toList());
}
}

View file

@ -2,6 +2,7 @@ package ru.redrise.marinesco;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
@Data
@ -10,14 +11,11 @@ public class UserSettingsForm {
@NotNull
@NotEmpty(message = "Display name could not be blank")
public String displayname;
@Pattern(regexp = "^[a-zA-Z0-9!#+\"\\-<>%^&*$@]{8,32}$|^$",
message = "Password must be at least 8 characters long. Should not exceed 32 characters")
public String newPassword;
public boolean isNewPasswordSet(){
return ! newPassword.isBlank();
}
public boolean isNewPasswordValid(){
final int newPasswordLength = newPassword.length();
return newPasswordLength > 8 && newPasswordLength < 32;
}
}

View file

@ -14,7 +14,7 @@ import jakarta.validation.Payload;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginOccupiedConstraint {
String message() default "Login already taken. Please use anohter one.";
String message() default "Login already taken. Please use another one";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View file

@ -12,9 +12,6 @@ public class LoginOccupiedValidator implements ConstraintValidator<LoginOccupied
@Autowired
private UserRepository userRepo;
@Override
public void initialize(LoginOccupiedConstraint constraintAnnotation) {}
@Override
public boolean isValid(String login, ConstraintValidatorContext context) {
return userRepo.findByUsername(login) == null;

View file

@ -3,12 +3,7 @@ package ru.redrise.marinesco.library;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -29,13 +24,13 @@ import ru.redrise.marinesco.settings.ApplicationSettings;
public class InpxScanner {
private static volatile String lastRunErrors = "";
private ThreadPoolTaskExecutor executor;
private LibraryMetadataRepository libraryMetadataRepository;
private AuthorRepository authorRepository;
private GenreRepository genreRepository;
private BookRepository bookRepository;
private final ThreadPoolTaskExecutor executor;
private final AuthorRepository authorRepository;
private final GenreRepository genreRepository;
private final BookRepository bookRepository;
private final LibraryMetadataRepository libraryMetadataRepository;
private String filesLocation;
private final String filesLocation;
public InpxScanner(ThreadPoolTaskExecutor executor,
ApplicationSettings applicationSettings,
@ -87,7 +82,7 @@ public class InpxScanner {
private File getInpxFile() throws Exception {
final FileSystemResource libraryLocation = new FileSystemResource(filesLocation);
return Stream.of(libraryLocation.getFile().listFiles())
return Arrays.stream(libraryLocation.getFile().listFiles())
.filter(file -> file.getName().endsWith(".inpx"))
.findFirst()
.get();

View file

@ -86,7 +86,7 @@ public class RepackZip {
}
} catch (Exception e) {
log.error("{}", e);
log.error(e.toString());
}
log.info("Complete: {}", container.getName());
}

View file

@ -47,17 +47,14 @@ public class GenreSettingsController {
genreRepository.findAll()
.iterator()
.forEachRemaining(element -> genres.add(element));
.forEachRemaining(genres::add);
return new GenresHolder(genres);
}
@PostMapping
public String getGenresUpdated(@ModelAttribute GenresHolder genreHolder) {
for (Genre genre : genreHolder.getGenres())
genreRepository.save(genre);
genreHolder.getGenres().forEach(genreRepository::save);
return "genres_settings";
}

View file

@ -14,16 +14,15 @@ import ru.redrise.marinesco.library.Genre;
@Slf4j
public class GenresUpload {
public static String upload(Resource resouce, long fileSize, GenreRepository repository) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resouce.getInputStream()))){
public static String upload(Resource resource, long fileSize, GenreRepository repository) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()))){
if (fileSize == 0)
throw new Exception("empty file");
String line;
List<Genre> genres = new ArrayList<>();
while ((line = reader.readLine()) != null) {
String arr[] = line.split(":::");
String[] arr = line.split(":::");
if (arr.length != 2)
throw new Exception("Malformed file");
@ -33,10 +32,10 @@ public class GenresUpload {
repository.saveAll(genres);
} catch (Exception e) {
log.debug("{}", e);
log.debug(e.toString());
return "Upload failed: " + e.getMessage();
}
return "Successfully uploaded: " + resouce.getFilename();
return "Successfully uploaded: " + resource.getFilename();
}
}

View file

@ -1,6 +1,7 @@
package ru.redrise.marinesco.library.web;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.springframework.stereotype.Controller;
@ -16,7 +17,7 @@ import ru.redrise.marinesco.library.Book;
@Controller
@RequestMapping("/author")
public class AuthorController {
private AuthorRepository authorRepository;
private final AuthorRepository authorRepository;
public AuthorController(AuthorRepository authorRepository){
this.authorRepository = authorRepository;
@ -33,10 +34,10 @@ public class AuthorController {
List<Book> books = author.getBooks();
Collections.sort(books, (a, b) -> a.getSeries().compareTo(b.getSeries()));
books.sort(Comparator.comparing(Book::getSeries));
model.addAttribute("author", author);
model.addAttribute("books", books);
model.addAttribute("author", author)
.addAttribute("books", books);
return "author";
}

View file

@ -12,7 +12,7 @@ import ru.redrise.marinesco.library.Book;
@Controller
@RequestMapping("/book")
public class BookController {
private BookRepository bookRepository;
private final BookRepository bookRepository;
public BookController(BookRepository bookRepository){
this.bookRepository = bookRepository;
@ -25,6 +25,7 @@ public class BookController {
model.addAttribute("Error", "Not found");
return "book";
}
model.addAttribute("book", book);
return "book";
}

View file

@ -19,8 +19,8 @@ import ru.redrise.marinesco.library.Book;
@RequestMapping("/search")
public class SearchController {
private BookRepository inpEntryRepository;
private AuthorRepository authorRepository;
private final BookRepository inpEntryRepository;
private final AuthorRepository authorRepository;
public SearchController(BookRepository bookRepository, AuthorRepository authorRepository){
this.inpEntryRepository = bookRepository;
@ -34,7 +34,7 @@ public class SearchController {
@RequestParam(value = "author", required = false) Boolean author,
Model model) {
if (search.trim().equals(""))
if (search.trim().isEmpty())
return "search";
model.addAttribute("searchPattern", search);
@ -46,21 +46,21 @@ public class SearchController {
if (title != null){
List<Book> books = inpEntryRepository.findByTitleContainingIgnoreCase(search);
if (books.size() != 0)
if (!books.isEmpty())
model.addAttribute("books", books);
model.addAttribute("isTitle", true);
}
if (series != null){
List<Book> bookSeries = inpEntryRepository.findBySeriesContainingIgnoreCase(search);
if (bookSeries.size() != 0)
if (!bookSeries.isEmpty())
model.addAttribute("series", bookSeries);
model.addAttribute("isSeries", true);
}
if (author != null){
List<Author> authors = authorRepository.findByAuthorNameContainingIgnoreCase(search);
if (authors.size() != 0)
if (!authors.isEmpty())
model.addAttribute("authors", authors);
model.addAttribute("isAuthor", true);
}

View file

@ -8,7 +8,7 @@ import ru.redrise.marinesco.data.RolesRepository;
@Component
public class AthorityByIdConverter implements Converter<Long, UserRole>{
private RolesRepository rolesRepo;
private final RolesRepository rolesRepo;
public AthorityByIdConverter(RolesRepository rolesRepo){
this.rolesRepo = rolesRepo;

View file

@ -40,7 +40,7 @@ public class ManageUsersController {
}
@ModelAttribute(name = "userGenerified")
public UserGenerified taco() {
public UserGenerified createUserGenerified() {
return new UserGenerified();
}
@ -92,7 +92,7 @@ public class ManageUsersController {
if (user == null)
return "redirect:/settings/manage_users";
user.setAuthorities(userGenerified.getAthorities());
user.setAuthorities(userGenerified.getAuthorities());
user.setDisplayname(userGenerified.getDisplayName());
String password = userGenerified.getPassword().trim();
if (! password.trim().isEmpty())
@ -114,7 +114,7 @@ public class ManageUsersController {
}
User user = userRepository.save(form.toUser(passwordEncoder));
log.info("Added user {} {} {}", user.getId(), user.getUsername(), user.getDisplayname(),
log.info("Added user {} {} {} {}", user.getId(), user.getUsername(), user.getDisplayname(),
user.getAuthorities().get(0));
// Reloads page therefore new records appears
return "redirect:/settings/manage_users";

View file

@ -21,12 +21,12 @@ import ru.redrise.marinesco.settings.ApplicationSettings;
@Controller
@RequestMapping("/register")
public class RegistrationController {
private UserRepository userRepo;
private RolesRepository rolesRepo;
private PasswordEncoder passwordEncoder;
private HttpServletRequest request;
private final UserRepository userRepo;
private final RolesRepository rolesRepo;
private final PasswordEncoder passwordEncoder;
private final HttpServletRequest request;
private ApplicationSettings applicationSettings;
private final ApplicationSettings applicationSettings;
public RegistrationController(UserRepository userRepo,
RolesRepository rolesRepo,
@ -54,10 +54,10 @@ public class RegistrationController {
@PostMapping
public String postMethodName(@Valid RegistrationForm form, Errors errors, Model model) {
if (!applicationSettings.isRegistrationAllowed())
if (! applicationSettings.isRegistrationAllowed())
return "redirect:/";
if (form.isPasswordsNotEqual()) {
model.addAttribute("passwordsMismatch", "Passwords must be the same.");
model.addAttribute("passwordsMismatch", "Passwords must be the same");
return "registration";
}
if (userRepo.findByUsername(form.getUsername()) != null){

View file

@ -29,14 +29,10 @@ public class UserRole implements GrantedAuthority{
if (type == null)
throw new UnsupportedOperationException("Unimplemented method 'getAuthority'");
switch (type) {
case USER:
return "ROLE_USER";
case ADMIN:
return "ROLE_ADMIN";
default:
throw new UnsupportedOperationException("Unimplemented method 'getAuthority'");
}
return switch (type) {
case USER -> "ROLE_USER";
case ADMIN -> "ROLE_ADMIN";
};
}
public enum Type{

View file

@ -60,19 +60,12 @@ public class UserSettingsController {
Model model){
if (errors.hasErrors())
return "user_settings";
if (! user.getDisplayname().equals(userSettingsForm.getDisplayname()))
user.setDisplayname(userSettingsForm.getDisplayname());
if (userSettingsForm.isNewPasswordSet()){
if (userSettingsForm.isNewPasswordValid()){
user.setPassword(passwordEncoder.encode(userSettingsForm.getNewPassword()));
}
else{
model.addAttribute("password_incorrect", "Password must be at least 8 characters long. Should not exceed 32 characters.");
return "user_settings";
}
}
log.info("{} {}", userSettingsForm.getDisplayname(), userSettingsForm.getNewPassword());
user.setDisplayname(userSettingsForm.getDisplayname());
if (userSettingsForm.isNewPasswordSet())
user.setPassword(passwordEncoder.encode(userSettingsForm.getNewPassword()));
userRepo.save(user);
return "redirect:/profile/settings";

View file

@ -18,8 +18,8 @@ import ru.redrise.marinesco.library.RepackZip;
public class SettingsController {
private ApplicationSettings applicationSettings;
private InpxScanner inpxScanner;
private RepackZip repackZip;
private final InpxScanner inpxScanner;
private final RepackZip repackZip;
public SettingsController(ApplicationSettings applicationSettings,
InpxScanner inpxScanner,

View file

@ -9,7 +9,7 @@ import ru.redrise.marinesco.security.UserRole;
@Component
public class RoleByIdConverter implements Converter<Long, UserRole>{
private RolesRepository rolesRepository;
private final RolesRepository rolesRepository;
public RoleByIdConverter(RolesRepository rolesRepository){
this.rolesRepository = rolesRepository;

View file

@ -22,10 +22,10 @@
<input type="text" name="displayname" id="displayname" th:value="${userSettingsForm.displayname}"
size="50%" /><br />
<span class="validationError" th:if="${password_incorrect} != null"
th:text="${password_incorrect}">false</span>
<span class="validationError" th:if="${#fields.hasErrors('newPassword')}"
th:errors="*{newPassword}">Error</span>
<br />
<label for="password">New password: </label>
<label for="newPassword">New password: </label>
<br />
<input type="password" name="newPassword" id="newPassword" size="50%" /><br />