added subject and entry classes, services and controllers

This commit is contained in:
Ksan 2025-10-22 20:49:53 +02:00
parent 65ff9d85dd
commit 7d3a9106dc
13 changed files with 532 additions and 38 deletions

View File

@ -0,0 +1,45 @@
package dev.ksan.etfoglasiserver.controller;
import dev.ksan.etfoglasiserver.dto.EntryDTO;
import dev.ksan.etfoglasiserver.model.Entry;
import dev.ksan.etfoglasiserver.service.EntryService;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EntryController {
@Autowired EntryService service;
@GetMapping("/entry")
public List<Entry> getEntries() {
return service.getEntries();
}
@GetMapping("/entry/{entryId}")
public Entry getEntry(@PathVariable UUID entryId) {
return service.getEntryById(entryId);
}
@PostMapping("/entry")
public void addEntry(@RequestBody EntryDTO entry) {
service.addEntry(entry);
}
@PutMapping("/entry")
public void updateEntry(@RequestBody EntryDTO entry) {
service.updateEntry(entry);
}
@DeleteMapping("/entry/{entryId}")
public void deleteEntry(@PathVariable UUID entryId) {
service.deleteEntry(entryId);
}
}

View File

@ -0,0 +1,44 @@
package dev.ksan.etfoglasiserver.controller;
import dev.ksan.etfoglasiserver.model.Subject;
import dev.ksan.etfoglasiserver.service.SubjectService;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SubjectController {
@Autowired SubjectService service;
@GetMapping("/subject")
public List<Subject> getSubjects() {
return service.getSubjects();
}
@GetMapping("/subject/{subjectId}")
public Subject getSubject(@PathVariable UUID subjectId) {
return service.getSubject(subjectId);
}
@PostMapping("/subject")
public void addSubject(@RequestBody Subject subject) {
service.addSubject(subject);
}
@PutMapping("/subject")
public void updateSubject(@RequestBody Subject subject) {
service.updateSubject(subject);
}
@DeleteMapping("/subject/{subjectId}")
public void deleteSubject(@PathVariable UUID subjectId) {
service.deleteSubject(subjectId);
}
}

View File

@ -1,10 +1,12 @@
package dev.ksan.etfoglasiserver.controller; package dev.ksan.etfoglasiserver.controller;
import dev.ksan.etfoglasiserver.dto.UserCreationDTO;
import dev.ksan.etfoglasiserver.dto.UserDTO;
import dev.ksan.etfoglasiserver.model.User; import dev.ksan.etfoglasiserver.model.User;
import dev.ksan.etfoglasiserver.service.UserService; import dev.ksan.etfoglasiserver.service.UserService;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -12,11 +14,29 @@ import org.springframework.web.bind.annotation.*;
public class UserController { public class UserController {
@Autowired UserService service; @Autowired UserService service;
@GetMapping("/users")
public List<UserDTO> getUsers() {
return service.getUsers().stream().map(this::getUserDTO).collect(Collectors.toList());
}
@GetMapping("users/{userId}")
public UserDTO getUserById(@PathVariable UUID userId) {
return getUserDTO(service.getUserById(userId));
}
public UserDTO getUserDTO(User user) {
return new UserDTO(user.getId(), user.getEmail());
}
/*
@GetMapping("/users") @GetMapping("/users")
public List<User> getUsers() { public List<User> getUsers() {
return service.getUsers(); return service.getUsers();
} }
@GetMapping("/users/{userId}") @GetMapping("/users/{userId}")
public User getUserById(@PathVariable UUID userId) { public User getUserById(@PathVariable UUID userId) {
return service.getUserById(userId); return service.getUserById(userId);
@ -32,6 +52,18 @@ public class UserController {
service.updateUser(user); service.updateUser(user);
} }
*/
@PutMapping("/users")
public void updateUser(@RequestBody UserCreationDTO user) {
service.updateUser(user);
}
@PostMapping("/users")
public void addUser(@RequestBody UserCreationDTO user) {
service.addUser(user);
}
@DeleteMapping("/users/{userId}") @DeleteMapping("/users/{userId}")
public void deleteUser(@PathVariable UUID userId) { public void deleteUser(@PathVariable UUID userId) {
service.deleteUser(userId); service.deleteUser(userId);

View File

@ -0,0 +1,70 @@
package dev.ksan.etfoglasiserver.dto;
import java.time.LocalDateTime;
import java.util.UUID;
public class EntryDTO {
private UUID id;
private String title;
private LocalDateTime time_published;
private String info_entry;
private String paragraph;
private String filepath;
private UUID subjectId;
public UUID getSubjectId() {
return subjectId;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public void setSubjectId(UUID subjectId) {
this.subjectId = subjectId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public LocalDateTime getTime_published() {
return time_published;
}
public void setTime_published(LocalDateTime time_published) {
this.time_published = time_published;
}
public String getInfo_entry() {
return info_entry;
}
public void setInfo_entry(String info_entry) {
this.info_entry = info_entry;
}
public String getParagraph() {
return paragraph;
}
public void setParagraph(String paragraph) {
this.paragraph = paragraph;
}
public String getFilepath() {
return filepath;
}
public void setFilepath(String filepath) {
this.filepath = filepath;
}
}

View File

@ -0,0 +1,26 @@
package dev.ksan.etfoglasiserver.dto;
public class UserCreationDTO {
private String email;
private String newEmail;
private String password;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNewEmail() {
return newEmail;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -1,43 +1,50 @@
package dev.ksan.etfoglasiserver.model; package dev.ksan.etfoglasiserver.model;
import dev.ksan.etfoglasiserver.dto.EntryDTO;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.springframework.stereotype.Component;
@Entity @Entity
@Table(name = "entries")
public class Entry { public class Entry {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
private UUID id; private UUID id;
@Column private long subjectId; @ManyToOne(fetch = FetchType.EAGER)
private String title; @JoinColumn(nullable = false)
private String date; private Subject subject;
private String info;
@Column private String title;
@Column private LocalDateTime time_published;
private String info_entry;
private String paragraph; private String paragraph;
private String filepath;
public Entry() {} public Entry() {}
public Entry(String title, String date, String info, List<String> paragraphs) {
this.title = title;
this.date = date;
this.info = info;
this.paragraph = String.join("\n", paragraph); public Entry(EntryDTO entry) {
} this.title = entry.getTitle();
this.paragraph = entry.getParagraph();
public Entry(String title, String date, String info, String paragraph) { this.info_entry = entry.getInfo_entry();
this.title = title; this.filepath = entry.getFilepath();
this.date = date; this.time_published = entry.getTime_published();
this.info = info;
this.paragraph = paragraph;
} }
public String getParagraph() { public String getParagraph() {
return paragraph; return paragraph;
} }
public Subject getSubject() {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
public void setParagraph(List<String> paragraphs) { public void setParagraph(List<String> paragraphs) {
this.paragraph = String.join("\n", paragraphs); this.paragraph = String.join("\n", paragraphs);
} }
@ -46,16 +53,19 @@ public class Entry {
this.paragraph = paragraph; this.paragraph = paragraph;
} }
public void setTitle(String title) {
this.title = title;
}
public String getTitle() { public String getTitle() {
return title; return title;
} }
public String getDate() { public LocalDateTime getDate() {
return date; return time_published;
} }
public String getInfo() { public String getInfo() {
return info; return info_entry;
} }
@Override @Override
@ -64,8 +74,8 @@ public class Entry {
if (o == null) return false; if (o == null) return false;
Entry subject = (Entry) o; Entry subject = (Entry) o;
if (title.equals(subject.getTitle()) if (title.equals(subject.getTitle())
&& date.equals(subject.getDate()) && time_published.equals(subject.getDate())
&& info.equals(subject.getInfo())) { && info_entry.equals(subject.getInfo())) {
return true; return true;
} }
return false; return false;
@ -73,6 +83,41 @@ public class Entry {
@Override @Override
public String toString() { public String toString() {
return title + " " + date + " " + info + "\n\t" + paragraph + "\n"; return "Entry{"
+ "id="
+ id
+ ", subject="
+ (subject != null ? subject.getId() : "null")
+ ", title='"
+ title
+ '\''
+ ", time_published="
+ time_published
+ ", info_entry='"
+ info_entry
+ '\''
+ ", paragraph='"
+ paragraph
+ '\''
+ ", filepath='"
+ filepath
+ '\''
+ '}';
}
public String getFilepath() {
return filepath;
}
public void setFilepath(String filepath) {
this.filepath = filepath;
}
public void setInfo_entry(String infoEntry) {
this.info_entry = infoEntry;
}
public void setTime_published(LocalDateTime timePublished) {
this.time_published = timePublished;
} }
} }

View File

@ -0,0 +1,46 @@
package dev.ksan.etfoglasiserver.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.UUID;
@Entity
@Table(name = "subjects")
public class Subject {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
@Column private long code;
@Column(nullable = false)
private String name;
public Subject(){
}
public UUID getId() {
return id;
}
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -1,7 +1,7 @@
package dev.ksan.etfoglasiserver.model; package dev.ksan.etfoglasiserver.model;
import dev.ksan.etfoglasiserver.dto.UserCreationDTO;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.UUID; import java.util.UUID;
@ -19,9 +19,20 @@ public class User {
@Column(nullable = false, length = 255) @Column(nullable = false, length = 255)
private String password; private String password;
@Column(nullable = false, updatable = false,insertable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") @Column(
nullable = false,
updatable = false,
insertable = false,
columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private LocalDateTime regTime; private LocalDateTime regTime;
public User() {}
public User(UserCreationDTO user) {
this.email = user.getEmail();
this.password = user.getPassword();
}
public UUID getId() { public UUID getId() {
return id; return id;
} }

View File

@ -0,0 +1,9 @@
package dev.ksan.etfoglasiserver.repository;
import dev.ksan.etfoglasiserver.model.Entry;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EntryRepo extends JpaRepository<Entry, UUID> {}

View File

@ -0,0 +1,11 @@
package dev.ksan.etfoglasiserver.repository;
import dev.ksan.etfoglasiserver.model.Subject;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface SubjectRepo extends JpaRepository<Subject, UUID> {
boolean existsByName(String name);
}

View File

@ -0,0 +1,67 @@
package dev.ksan.etfoglasiserver.service;
import dev.ksan.etfoglasiserver.dto.EntryDTO;
import dev.ksan.etfoglasiserver.model.Entry;
import dev.ksan.etfoglasiserver.model.Subject;
import dev.ksan.etfoglasiserver.repository.EntryRepo;
import dev.ksan.etfoglasiserver.repository.SubjectRepo;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EntryService {
@Autowired EntryRepo entryRepo;
@Autowired SubjectRepo subjectRepo;
public List<Entry> getEntries() {
return entryRepo.findAll();
}
public Entry getEntryById(UUID id) {
return entryRepo.findById(id).orElseThrow(() -> new RuntimeException("Entry not found"));
}
public void addEntry(EntryDTO entry) {
Subject subject =
subjectRepo
.findById(entry.getSubjectId())
.orElseThrow(() -> new RuntimeException("Subject not found"));
Entry newEntry = new Entry(entry);
newEntry.setSubject(subject);
entryRepo.save(newEntry);
}
public void updateEntry(EntryDTO entry) {
Subject subject =
subjectRepo
.findById(entry.getSubjectId())
.orElseThrow(() -> new RuntimeException("Subject not found"));
Entry updateEntry = entryRepo.findById(entry.getId()).orElseThrow(() -> new RuntimeException("Entry not found"));
updateEntry.setSubject(subject);
if (entry.getTitle() != null) {
updateEntry.setTitle(entry.getTitle());
}
if (entry.getInfo_entry() != null) {
updateEntry.setInfo_entry(entry.getInfo_entry());
}
if (entry.getParagraph() != null) {
updateEntry.setParagraph(entry.getParagraph());
}
if (entry.getFilepath() != null) {
updateEntry.setFilepath(entry.getFilepath());
}
if (entry.getTime_published() != null) {
updateEntry.setTime_published(entry.getTime_published());
}
entryRepo.save(updateEntry);
}
public void deleteEntry(UUID id) {
entryRepo.deleteById(id);
}
}

View File

@ -0,0 +1,47 @@
package dev.ksan.etfoglasiserver.service;
import dev.ksan.etfoglasiserver.model.Subject;
import dev.ksan.etfoglasiserver.repository.SubjectRepo;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SubjectService {
@Autowired SubjectRepo subjectRepo;
public List<Subject> getSubjects() {
return subjectRepo.findAll();
}
public Subject getSubject(UUID id) {
return subjectRepo.findById(id).orElseThrow(() -> new RuntimeException("Subject not found"));
}
public void addSubject(Subject subject) {
if( subjectRepo.existsByName(subject.getName())) {
throw new RuntimeException("Subject already exists");
}
Subject newSubject = new Subject();
newSubject.setName(subject.getName());
newSubject.setCode(subject.getCode());
subjectRepo.save(newSubject);
}
public void updateSubject(Subject subject) {
Subject existingSubject = subjectRepo.findById(subject.getId()).orElseThrow(()-> new RuntimeException("Subject not found"));
existingSubject.setName(subject.getName());
existingSubject.setCode(subject.getCode());
subjectRepo.save(existingSubject);
}
public void deleteSubject(UUID id) {
subjectRepo.deleteById(id);
}
}

View File

@ -1,19 +1,21 @@
package dev.ksan.etfoglasiserver.service; package dev.ksan.etfoglasiserver.service;
import dev.ksan.etfoglasiserver.dto.UserCreationDTO;
import dev.ksan.etfoglasiserver.model.User; import dev.ksan.etfoglasiserver.model.User;
import dev.ksan.etfoglasiserver.repository.UserRepo; import dev.ksan.etfoglasiserver.repository.UserRepo;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
@Transactional
public class UserService { public class UserService {
@Autowired UserRepo userRepo; @Autowired UserRepo userRepo;
public List<User> getUsers() { public List<User> getUsers() {
System.out.println("getUsers");
return userRepo.findAll(); return userRepo.findAll();
} }
@ -21,18 +23,56 @@ public class UserService {
return userRepo.findById(userId).orElseThrow(() -> new RuntimeException("User not found")); return userRepo.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));
} }
public void addUser(User user) { public void addUser(UserCreationDTO user) {
if(userRepo.findByEmail(user.getEmail()) != null) {
if (userRepo.findByEmail(user.getEmail()).isPresent()) {
throw new RuntimeException("User already exists"); throw new RuntimeException("User already exists");
} }
if(this.isValidEmail(user.getEmail())) { if (this.isValidEmail(user.getEmail())) {
userRepo.save(new User(user));
}
}
public void addUser(User user) {
if (userRepo.findByEmail(user.getEmail()).isPresent()) {
throw new RuntimeException("User already exists");
}
if (this.isValidEmail(user.getEmail())) {
userRepo.save(user); userRepo.save(user);
} }
} }
public void updateUser(UserCreationDTO user) {
Optional<User> existingUserOpt = userRepo.findByEmail(user.getEmail());
if (userRepo.findByEmail(user.getEmail()).isPresent()) {
if (this.isValidEmail(user.getEmail())) {
if (this.isValidPassword(user.getPassword())) {
User existingUser = existingUserOpt.get();
/*
if(user.getNewEmail() == null){
existingUser.setEmail(user.getEmail());
}else{
existingUser.setEmail(user.getNewEmail());
}
*/
existingUser.setEmail(user.getEmail());
existingUser.setPassword(user.getPassword());
userRepo.save(existingUser);
} else throw new RuntimeException("Password too short");
} else throw new RuntimeException("Invalid email");
} else throw new RuntimeException("User not found");
}
public void updateUser(User user) { public void updateUser(User user) {
if(this.isValidEmail(user.getEmail())) { if (this.isValidEmail(user.getEmail())) {
userRepo.save(user); userRepo.save(user);
} }
@ -41,19 +81,20 @@ public class UserService {
public void deleteUser(UUID userId) { public void deleteUser(UUID userId) {
userRepo.deleteById(userId); userRepo.deleteById(userId);
} }
public boolean isValidEmail(String email) { public boolean isValidEmail(String email) {
if(email == null) { if (email == null) {
return false; return false;
} }
String regex = "^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"; String regex = "^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
if (email.length() < 256 && email.matches(regex)) {
if(email.length() < 256 &&email.matches(regex)){
System.out.println(email.length());
System.out.println("Email address is too long");
return true; return true;
} }
throw new RuntimeException("Invalid email"); throw new RuntimeException("Invalid email");
}
public boolean isValidPassword(String pass) {
return pass.length() >= 8;
} }
} }