Compare commits
2 Commits
master
...
LabWork_04
Author | SHA1 | Date | |
---|---|---|---|
071b9813d7 | |||
93e11b8537 |
23
library-ui/.gitignore
vendored
Normal file
23
library-ui/.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
24
library-ui/README.md
Normal file
24
library-ui/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# library-ui
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
5
library-ui/babel.config.js
Normal file
5
library-ui/babel.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
19
library-ui/jsconfig.json
Normal file
19
library-ui/jsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
12033
library-ui/package-lock.json
generated
Normal file
12033
library-ui/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
43
library-ui/package.json
Normal file
43
library-ui/package.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "library-ui",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"vue": "^3.2.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "@babel/eslint-parser"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead",
|
||||
"not ie 11"
|
||||
]
|
||||
}
|
BIN
library-ui/public/favicon.ico
Normal file
BIN
library-ui/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
17
library-ui/public/index.html
Normal file
17
library-ui/public/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
26
library-ui/src/App.vue
Normal file
26
library-ui/src/App.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<img alt="Vue logo" src="./assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
HelloWorld
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
BIN
library-ui/src/assets/logo.png
Normal file
BIN
library-ui/src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
58
library-ui/src/components/HelloWorld.vue
Normal file
58
library-ui/src/components/HelloWorld.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
4
library-ui/src/main.js
Normal file
4
library-ui/src/main.js
Normal file
@ -0,0 +1,4 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
|
||||
createApp(App).mount('#app')
|
4
library-ui/vue.config.js
Normal file
4
library-ui/vue.config.js
Normal file
@ -0,0 +1,4 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true
|
||||
})
|
@ -19,6 +19,9 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
||||
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.6.0'
|
||||
runtimeOnly 'com.h2database:h2'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
|
BIN
network/data/home.mv.db
Normal file
BIN
network/data/home.mv.db
Normal file
Binary file not shown.
3
network/data/home.trace.db
Normal file
3
network/data/home.trace.db
Normal file
@ -0,0 +1,3 @@
|
||||
2024-11-25 15:24:18.380541+04:00 jdbc[3]: exception
|
||||
org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "AUTHOR" not found (this database is empty); SQL statement:
|
||||
insert into author (email,first_name,last_name,password,id) values (?,?,?,?,default) [42104-224]
|
@ -0,0 +1,40 @@
|
||||
package com.ulstu.network.advice;
|
||||
|
||||
import com.ulstu.network.exceptions.AuthorNotFoundException;
|
||||
import com.ulstu.network.exceptions.BookNotFoundException;
|
||||
import com.ulstu.network.exceptions.ValidationException;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ControllerAdvice
|
||||
public class AdviceController {
|
||||
@ExceptionHandler({
|
||||
AuthorNotFoundException.class,
|
||||
BookNotFoundException.class,
|
||||
ValidationException.class
|
||||
})
|
||||
public ResponseEntity<Object> handleException(Throwable e) {
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<Object> handleBindException(MethodArgumentNotValidException e) {
|
||||
final ValidationException validationException = new ValidationException(
|
||||
e.getBindingResult().getAllErrors().stream()
|
||||
.map(DefaultMessageSourceResolvable::getDefaultMessage)
|
||||
.collect(Collectors.toSet()));
|
||||
return handleException(validationException);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<Object> handleUnknownException(Throwable e) {
|
||||
e.printStackTrace();
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.ulstu.network.controllers;
|
||||
|
||||
import com.ulstu.network.dto.AuthorDTO;
|
||||
import com.ulstu.network.models.Author;
|
||||
import com.ulstu.network.services.AuthorService;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/author")
|
||||
public class AuthorController {
|
||||
private final AuthorService authorService;
|
||||
|
||||
public AuthorController(AuthorService authorService){
|
||||
this.authorService = authorService;
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public AuthorDTO getAuthor(@PathVariable Long id) {
|
||||
return new AuthorDTO(authorService.findAuthor(id));
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public List<AuthorDTO> getAuthors() {
|
||||
return authorService.findAllAuthors().stream()
|
||||
.map(AuthorDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public AuthorDTO createAuthor(@RequestBody @Valid Author author) {
|
||||
return new AuthorDTO(authorService.addAuthor(author));
|
||||
}
|
||||
|
||||
@PostMapping("/{id}")
|
||||
public AuthorDTO attachBookToAuthor(@PathVariable Long id, @RequestParam Long bookId) {
|
||||
return new AuthorDTO(authorService.attachBookToAuthor(id, bookId));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public AuthorDTO updateAuthor(@PathVariable Long id, @RequestBody @Valid Author author ){
|
||||
return new AuthorDTO(authorService.updateAuthor(id, author));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void deleteAuthor(@PathVariable Long id){
|
||||
authorService.deleteAuthor(id);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.ulstu.network.controllers;
|
||||
|
||||
import com.ulstu.network.dto.BookDTO;
|
||||
import com.ulstu.network.dto.BookDataDTO;
|
||||
import com.ulstu.network.models.Book;
|
||||
import com.ulstu.network.services.BookService;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/book")
|
||||
public class BookController {
|
||||
private final BookService bookService;
|
||||
|
||||
public BookController(BookService bookService) { this.bookService = bookService; }
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public BookDTO getBook(@PathVariable long id) { return new BookDTO(bookService.findBook(id)); }
|
||||
|
||||
@GetMapping
|
||||
public List<BookDTO> getBooks() {
|
||||
return bookService.findAllBooks().stream()
|
||||
.map(BookDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public BookDTO createBook(@RequestBody @Valid BookDataDTO bookData) {
|
||||
return new BookDTO(bookService.addBook(bookData));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public BookDTO updateBook(@PathVariable Long id, @RequestBody @Valid BookDataDTO bookData) {
|
||||
return new BookDTO(bookService.updateBook(id, bookData));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void deleteBook(@PathVariable Long id) {bookService.deleteBook(id);}
|
||||
}
|
34
network/src/main/java/com/ulstu/network/dto/AuthorDTO.java
Normal file
34
network/src/main/java/com/ulstu/network/dto/AuthorDTO.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.ulstu.network.dto;
|
||||
|
||||
import com.ulstu.network.models.Author;
|
||||
import com.ulstu.network.models.Book;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AuthorDTO {
|
||||
private final long id;
|
||||
private final String name;
|
||||
private final String email;
|
||||
private final List<Book> books;
|
||||
|
||||
public AuthorDTO(Author author) {
|
||||
this.id = author.getId();
|
||||
this.name = String.format("%s %s", author.getFirstName(), author.getLastName());
|
||||
this.email = author.getEmail();
|
||||
this.books = author.getBooks();
|
||||
}
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public List<Book> getBooks(){
|
||||
return books;
|
||||
}
|
||||
}
|
25
network/src/main/java/com/ulstu/network/dto/BookDTO.java
Normal file
25
network/src/main/java/com/ulstu/network/dto/BookDTO.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.ulstu.network.dto;
|
||||
|
||||
import com.ulstu.network.models.Author;
|
||||
import com.ulstu.network.models.Book;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BookDTO {
|
||||
private final long id;
|
||||
private final String title;
|
||||
private final String isbn;
|
||||
private final List<Author> authors;
|
||||
|
||||
public BookDTO(Book book) {
|
||||
this.id = book.getId();
|
||||
this.title = book.getTitle();
|
||||
this.isbn = book.getIsbn();
|
||||
this.authors = book.getAuthors();
|
||||
}
|
||||
|
||||
public long getId() {return id;}
|
||||
public String getTitle() {return title;}
|
||||
public String getIsbn() {return isbn;}
|
||||
public List<Author> getAuthors() {return authors;}
|
||||
}
|
39
network/src/main/java/com/ulstu/network/dto/BookDataDTO.java
Normal file
39
network/src/main/java/com/ulstu/network/dto/BookDataDTO.java
Normal file
@ -0,0 +1,39 @@
|
||||
package com.ulstu.network.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BookDataDTO {
|
||||
@NotBlank(message = "Title can't be empty")
|
||||
private String title;
|
||||
|
||||
@NotBlank(message = "ISBN can't be empty")
|
||||
private String isbn;
|
||||
|
||||
private List<Long> authors;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getIsbn() {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public void setIsbn(String isbn) {
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
public List<Long> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(List<Long> authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package com.ulstu.network.dto;
|
||||
|
||||
public class LibraryDTO {
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.ulstu.network.exceptions;
|
||||
|
||||
public class AuthorNotFoundException extends RuntimeException{
|
||||
public AuthorNotFoundException(Long id){
|
||||
super(String.format("Author with id [%s] is not found", id));
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.ulstu.network.exceptions;
|
||||
|
||||
public class BookNotFoundException extends RuntimeException{
|
||||
public BookNotFoundException(Long id){
|
||||
super(String.format("Book with id [%s] is not found", id));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
package com.ulstu.network.exceptions;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class ValidationException extends RuntimeException {
|
||||
public <T> ValidationException(Set<String> errors) {
|
||||
super(String.join("\n", errors));
|
||||
}
|
||||
}
|
85
network/src/main/java/com/ulstu/network/models/Author.java
Normal file
85
network/src/main/java/com/ulstu/network/models/Author.java
Normal file
@ -0,0 +1,85 @@
|
||||
package com.ulstu.network.models;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
public class Author {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
@NotBlank(message = "First Name can't be empty")
|
||||
private String firstName;
|
||||
|
||||
@Column(nullable = false)
|
||||
@NotBlank(message = "Last Name can't be empty")
|
||||
private String lastName;
|
||||
|
||||
@Email(message = "Please enter a correct email address")
|
||||
@NotBlank(message = "Email can't be empty")
|
||||
private String email;
|
||||
|
||||
/*@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\\\d).{8}$",
|
||||
message = "Password is not valid")*/
|
||||
@NotBlank
|
||||
private String password;
|
||||
|
||||
@ManyToMany(cascade = CascadeType.ALL)
|
||||
@JoinTable(name = "book_author", joinColumns = @JoinColumn(name = "book_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "author_id", referencedColumnName = "id"))
|
||||
private List<Book> books;
|
||||
|
||||
public Author() {
|
||||
}
|
||||
|
||||
public Author(String firstName, String lastName, String email, String password) {
|
||||
super();
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
}
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public void setEmail (String email) { this.email = email; }
|
||||
|
||||
public String getEmail () { return email; }
|
||||
|
||||
public void setPassword (String password) { this.password = password; }
|
||||
|
||||
public String getPassword () { return password; }
|
||||
|
||||
public List<Book> getBooks() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void setBooks(List<Book> books) {
|
||||
this.books = books;
|
||||
}
|
||||
}
|
64
network/src/main/java/com/ulstu/network/models/Book.java
Normal file
64
network/src/main/java/com/ulstu/network/models/Book.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.ulstu.network.models;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
public class Book {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String title;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String isbn;
|
||||
|
||||
@ManyToMany(mappedBy = "books", fetch = FetchType.EAGER)
|
||||
private List<Author> authors;
|
||||
|
||||
public Book() {
|
||||
}
|
||||
|
||||
public Book(String title, String isbn) {
|
||||
super();
|
||||
this.title = title;
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getIsbn() {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public void setIsbn(String isbn) {
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
public List<Author> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(List<Author> authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
}
|
66
network/src/main/java/com/ulstu/network/models/Library.java
Normal file
66
network/src/main/java/com/ulstu/network/models/Library.java
Normal file
@ -0,0 +1,66 @@
|
||||
package com.ulstu.network.models;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
public class Library {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
@Column
|
||||
private String address;
|
||||
|
||||
@OneToMany
|
||||
@JoinTable(name = "books_in_library",
|
||||
joinColumns = @JoinColumn(name = "library_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "book_id"))
|
||||
private List<Book> books;
|
||||
|
||||
public Library() {
|
||||
}
|
||||
|
||||
public Library(String name) {
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public List<Book> getBooks() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void setBooks(List<Book> books) {
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
}
|
69
network/src/main/java/com/ulstu/network/models/User.java
Normal file
69
network/src/main/java/com/ulstu/network/models/User.java
Normal file
@ -0,0 +1,69 @@
|
||||
package com.ulstu.network.models;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "USERS")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@Column
|
||||
private String name;
|
||||
|
||||
@Column
|
||||
private String email;
|
||||
|
||||
@Column
|
||||
private String password;
|
||||
|
||||
@ManyToMany(cascade = {CascadeType.ALL})
|
||||
@JoinTable(name="user_books",
|
||||
joinColumns=@JoinColumn(name="user_id", referencedColumnName = "id"),
|
||||
inverseJoinColumns=@JoinColumn(name="book_id", referencedColumnName = "id"))
|
||||
private List<Book> books;
|
||||
|
||||
public User(){
|
||||
}
|
||||
|
||||
public User(String name, String email, String password){
|
||||
super();
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setName (String name) { this.name = name; }
|
||||
|
||||
public String getName () { return name; }
|
||||
|
||||
public void setEmail (String email) { this.email = email; }
|
||||
|
||||
public String getEmail () { return email; }
|
||||
|
||||
public void setPassword (String password) { this.password = password; }
|
||||
|
||||
public String getPassword () { return password; }
|
||||
|
||||
public List<Book> getBooks() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void setBooks(List<Book> books) {
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
public void addBook(Book book) { this.books.add(book); }
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.ulstu.network.repositories;
|
||||
|
||||
import com.ulstu.network.models.Author;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface AuthorRepository extends JpaRepository<Author, Long> {}
|
@ -0,0 +1,6 @@
|
||||
package com.ulstu.network.repositories;
|
||||
|
||||
import com.ulstu.network.models.Book;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface BookRepository extends JpaRepository<Book, Long> {}
|
@ -0,0 +1,11 @@
|
||||
package com.ulstu.network.repositories;
|
||||
|
||||
import com.ulstu.network.models.Library;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LibraryRepository extends JpaRepository<Library, Long> {}
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.ulstu.network.repositories;
|
||||
|
||||
import com.ulstu.network.models.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.ulstu.network.services;
|
||||
|
||||
import com.ulstu.network.models.Book;
|
||||
import com.ulstu.network.repositories.BookRepository;
|
||||
import com.ulstu.network.validation.ValidatorUtil;
|
||||
import com.ulstu.network.exceptions.AuthorNotFoundException;
|
||||
import com.ulstu.network.models.Author;
|
||||
import com.ulstu.network.repositories.AuthorRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class AuthorService {
|
||||
private final AuthorRepository authorRepository;
|
||||
private final BookService bookService;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public AuthorService(AuthorRepository authorRepository, BookService bookService, ValidatorUtil validatorUtil){
|
||||
this.authorRepository = authorRepository;
|
||||
this.bookService = bookService;
|
||||
this.validatorUtil = validatorUtil;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Author findAuthor(Long id) {
|
||||
return authorRepository.findById(id).orElseThrow(()->new AuthorNotFoundException(id));
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Author> findAllAuthors() {
|
||||
return authorRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Author addAuthor(Author author) {
|
||||
validatorUtil.validate(author);
|
||||
|
||||
return authorRepository.save(author);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Author attachBookToAuthor(Long authorId, Long bookId) {
|
||||
final Author currentAuthor = findAuthor(authorId);
|
||||
currentAuthor.getBooks().add(bookService.findBook(bookId));
|
||||
|
||||
return authorRepository.save(currentAuthor);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Author updateAuthor(Long id, Author author) {
|
||||
validatorUtil.validate(author);
|
||||
final Author currentAuthor = findAuthor(id);
|
||||
currentAuthor.setFirstName(author.getFirstName());
|
||||
currentAuthor.setLastName(author.getLastName());
|
||||
currentAuthor.setEmail(author.getEmail());
|
||||
currentAuthor.setPassword(author.getPassword());
|
||||
|
||||
return authorRepository.save(currentAuthor);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteAuthor(Long id) {
|
||||
final Author currentAuthor = findAuthor(id);
|
||||
authorRepository.delete(currentAuthor);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteAllAuthors() {
|
||||
authorRepository.deleteAll();
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.ulstu.network.services;
|
||||
|
||||
import com.ulstu.network.dto.BookDataDTO;
|
||||
import com.ulstu.network.exceptions.AuthorNotFoundException;
|
||||
import com.ulstu.network.exceptions.BookNotFoundException;
|
||||
import com.ulstu.network.models.Author;
|
||||
import com.ulstu.network.models.Book;
|
||||
import com.ulstu.network.repositories.AuthorRepository;
|
||||
import com.ulstu.network.repositories.BookRepository;
|
||||
import com.ulstu.network.validation.ValidatorUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
@Service
|
||||
public class BookService {
|
||||
private final BookRepository bookRepository;
|
||||
private final AuthorRepository authorRepository;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public BookService(BookRepository bookRepository, AuthorRepository authorRepository, ValidatorUtil validatorUtil){
|
||||
this.bookRepository = bookRepository;
|
||||
this.authorRepository = authorRepository;
|
||||
this.validatorUtil = validatorUtil;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Book findBook(Long id) {
|
||||
return bookRepository.findById(id).orElseThrow(()->new BookNotFoundException(id));
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Book> findAllBooks() {
|
||||
return bookRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Book addBook(BookDataDTO bookData) {
|
||||
validatorUtil.validate(bookData);
|
||||
|
||||
Book newBook = new Book(bookData.getTitle(), bookData.getIsbn());
|
||||
|
||||
List<Author> authors = new ArrayList<>();
|
||||
for (long id : bookData.getAuthors())
|
||||
{
|
||||
authorRepository.findById(id).ifPresent(authors::add);
|
||||
}
|
||||
newBook.setAuthors(authors);
|
||||
|
||||
return bookRepository.save(newBook);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Book updateBook(Long id, BookDataDTO bookData) {
|
||||
validatorUtil.validate(bookData);
|
||||
|
||||
final Book currentBook = findBook(id);
|
||||
currentBook.setTitle(bookData.getTitle());
|
||||
currentBook.setIsbn(bookData.getIsbn());
|
||||
|
||||
List<Author> authors = emptyList();
|
||||
for (long auth : bookData.getAuthors())
|
||||
{
|
||||
authorRepository.findById(auth).ifPresent(authors::add);
|
||||
}
|
||||
currentBook.setAuthors(authors);
|
||||
|
||||
return bookRepository.save(currentBook);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteBook(Long id) {
|
||||
final Book currentBook = findBook(id);
|
||||
bookRepository.delete(currentBook);
|
||||
}
|
||||
|
||||
public void deleteAllBooks(){
|
||||
bookRepository.deleteAll();
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package com.ulstu.network.services;
|
||||
|
||||
public class LibraryService {
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
package com.ulstu.network.swagger;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
public class SwaggerConfig {
|
||||
@Bean
|
||||
public Docket api() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("com.example.controller")) // Replace with your controller package
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
*/
|
@ -0,0 +1,26 @@
|
||||
package com.ulstu.network.validation;
|
||||
|
||||
import com.ulstu.network.exceptions.ValidationException;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.Validation;
|
||||
import jakarta.validation.Validator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class ValidatorUtil {
|
||||
private final Validator validator;
|
||||
public ValidatorUtil() {
|
||||
this.validator = Validation.buildDefaultValidatorFactory().getValidator();
|
||||
}
|
||||
public <T> void validate(T object) {
|
||||
final Set<ConstraintViolation<T>> errors = validator.validate(object);
|
||||
if (!errors.isEmpty()) {
|
||||
throw new ValidationException(errors.stream()
|
||||
.map(ConstraintViolation::getMessage)
|
||||
.collect(Collectors.toSet()));
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +1,10 @@
|
||||
spring.application.name=network
|
||||
|
||||
# H2 Database
|
||||
spring.h2.console.enabled=true
|
||||
spring.datasource.url=jdbc:h2:file:C://tmp/data
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=password
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||
|
Loading…
x
Reference in New Issue
Block a user