Compare commits

...

13 Commits
main ... lab5

Author SHA1 Message Date
parap
69466dca35 lab5 refactoring 2023-05-15 19:08:42 +04:00
parap
c793d802ef lab5 full 2023-05-02 09:10:59 +04:00
parap
e4c17f1642 Merge branch 'lab4' of http://student.git.athene.tech/maxKarme/PIbd-22_Karamushko_M_K_IP_Labs into lab5 2023-05-01 23:05:53 +04:00
parap
c7b8f30077 lab 5 main part 2023-05-01 23:05:23 +04:00
parap
f9febea780 dop catalog 2023-05-01 01:24:56 +04:00
parap
1586beb53b frontend changes 2023-05-01 01:24:31 +04:00
parap
efd20a1796 5 lab start 2023-05-01 01:23:12 +04:00
parap
651d1a95f4 4 lab full 2023-04-30 23:07:58 +04:00
parap
4d916bdfe6 fix 2023-04-29 18:01:53 +04:00
parap
901f388780 4 lab first step 2023-04-29 18:00:04 +04:00
parap
e739ceadec third lab 2023-04-17 12:53:57 +03:00
MaxKarme
995e104e86 third lab 2023-03-25 18:30:02 +04:00
MaxKarme
e3ddc3f4b3 second lab 2023-02-27 16:42:27 +03:00
98 changed files with 30039 additions and 349 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@ build/
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans

View File

@ -14,6 +14,21 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
implementation 'org.webjars:bootstrap:5.1.3'
implementation 'org.webjars:jquery:3.6.0'
implementation 'org.webjars:font-awesome:6.1.0'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.210'
implementation 'org.hibernate.validator:hibernate-validator'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

BIN
data.mv.db Normal file

Binary file not shown.

8235
data.trace.db Normal file

File diff suppressed because it is too large Load Diff

23
frontend/.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

0
frontend/README.md Normal file
View File

26
frontend/data.json Normal file
View File

@ -0,0 +1,26 @@
{
"films": [
{
"id": 1,
"name": "film super",
"genre": "Комедия"
}
],
"genres": [
{
"name": "",
"genre": "Драма",
"id": 1
},
{
"name": "",
"genre": "Комедия",
"id": 2
},
{
"name": "",
"genre": "Трилер",
"id": 3
}
]
}

View File

@ -1,42 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<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="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css">
<title>Document</title>
</head>
<body>
<form class="" id="form">
<h2>Калькулятор</h2>
<div class="container row">
<div class="form-group col-3">
<label for="formGroupExampleInput">X</label>
<input name="x" type="number" class="form-control col-3" placeholder="Первый аргумент">
</div>
<div class="form-group col-3">
<label for="formGroupExampleInput">Оператор</label>
<select name="selected" id="inputState" class="form-control">
<option selected>+</option>
<option>-</option>
<option>*</option>
<option>**</option>
<option>/</option>
</select>
</div>
<div class="form-group col-3">
<label for="formGroupExampleInput2">Y</label>
<input name="y" type="number" class="form-control col-3" placeholder="Второй аргумент">
</div>
</div>
<button type="submit" class="btn btn-primary m-3">Посчитать</button>
</form>
<h2 class="text" id="res"></h2>
<script src="./node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="../js/script.js"></script>
</body>
</html>

View File

@ -1,44 +0,0 @@
let form = document.getElementById("form");
let info = document.getElementById("res");
form.onsubmit = async (e) => {
e.preventDefault();
if(form.x.value === "") return;
if(form.y.value === "") return;
let index = form.selected.selectedIndex;
let op = form.selected.options[index].textContent;
let res = "";
switch(op) {
case "+":
res = await fetch(`http://localhost:8080/sum?x=${form.x.value}&y=${form.y.value}`)
res = await res.text();
break;
case "-":
res = await fetch(`http://localhost:8080/diff?x=${form.x.value}&y=${form.y.value}`)
res = await res.text();
break;
case "*":
res = await fetch(`http://localhost:8080/multiply?x=${form.x.value}&y=${form.y.value}`)
res = await res.text();
break;
case "**":
res = await fetch(`http://localhost:8080/degree?x=${form.x.value}&y=${form.y.value}`)
res = await res.text();
break;
case "/":
if(form.y.value == 0) return;
res = await fetch(`http://localhost:8080/divide?x=${form.x.value}&y=${form.y.value}`)
res = await res.text();
break;
}
info.textContent = res;
}

17929
frontend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,43 @@
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "http-server -p 3000 -c-1 -o ./"
},
"author": "",
"license": "ISC",
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.2.3",
"http-server": "^14.1.1"
"json-server": "^0.17.1",
"npm-run-all": "^4.1.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.5",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"fake-server": "json-server data.json -p 8079",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js" integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V" crossorigin="anonymous"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

0
frontend/src/App.css Normal file
View File

40
frontend/src/App.js Normal file
View File

@ -0,0 +1,40 @@
import './App.css';
import {BrowserRouter, Routes, Route} from "react-router-dom";
import Header from './components/common/Header';
import Home from './components/pages/Home';
import Films from './components/pages/Films';
import Film from './components/pages/Film';
import Contacts from './components/pages/Contacts';
import Catalogs from './components/pages/Catalogs';
import CatalogFilms from './components/catalogs/CatalogFilms';
import CatalogGenres from './components/catalogs/CatalogGenres';
import CatalogActors from './components/catalogs/CatalogActors';
const links = [
{id: 1, text: "Главная", path: ""},
{id: 2, text: "Фильмы", path: "films"},
{id: 3, text: "Контакты", path: "contacts"},
{id: 4, text: "Каталог", path: "catalogs"},
];
function App() {
return (
<>
<BrowserRouter>
<Header links={links}/>
<Routes path="/">
<Route index element={<Home/>}></Route>
<Route path="films" element={<Films/>}/>
<Route path="film" element={<Film/>}/>
<Route path="contacts" element={<Contacts/>}/>
<Route path="catalogs" element={<Catalogs/>}/>
<Route path="catalogs/catalogFilms" element={<CatalogFilms />}/>
<Route path="catalogs/catalogGenres" element={<CatalogGenres />}/>
<Route path="catalogs/catalogActors" element={<CatalogActors />}/>
</Routes>
</BrowserRouter>
</>
);
}
export default App;

View File

@ -0,0 +1,22 @@
.banner-block {
width: 90%;
}
.banner-card {
width: 0;
height: 0;
overflow: hidden;
opacity: 0.2;
transition: 0.5s opacity ease;
}
.banner-card.active {
width: 100%;
height: auto;
opacity: 1;
margin: 0 auto;
}
.banner-card.active img {
height: 75vh;
}

View File

@ -0,0 +1,29 @@
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import "./Banner.css";
export default function Banner(props) {
const [currentImage, setCurrent] = useState(1);
useEffect(() => {
let timer = setInterval(() => {
setCurrent(prev => {
return prev === 5 ? 1 : prev + 1;
});
}, 3000)
return clearInterval.bind(this, timer);
}, [])
return (
<div className="banner-block" id="banner">
{props.images.map(({img, id}) => (
<div key={id} className={"banner-card" + (id === currentImage ? " active" : "")}>
<Link to="film">
<img src={img} alt="" className=""/>
</Link>
</div>
))}
</div>
)
}

View File

@ -0,0 +1,51 @@
import Catalog from "../common/Catalog";
import { useEffect, useState } from "react";
import DataService from "../../services/DataService";
let headers = [
{label: "name", text: "Имя"},
{label: "surname", text: "Фамилия"}
]
export default function CatalogActors() {
const url = "/actors";
const [data, setData] = useState({
name: "",
surname: ""
});
const [actors, setActors] = useState([]);
function handleFormChange(e) {
setData({ ...data, [e.target.id]: e.target.value })
}
function onAdd() {
setData({name: "", genre: actors[0]});
}
function onChange(data) {
setData(data);
}
function validate(data) {
if(data.name === "") return false;
return true;
}
return (
<Catalog url={url} headers={headers} data={data} onAdd={onAdd} onChange={onChange} validate={validate}>
<div className="mb-3">
<label htmlFor="name" className="form-label">Имя</label>
<input type="text" value={data.name} id="name" className="form-control" required autoComplete="off"
onChange={handleFormChange}/>
<label htmlFor="surname" className="form-label">Фамилия</label>
<input type="text" value={data.surname} id="surname" className="form-control" required autoComplete="off"
onChange={handleFormChange}/>
</div>
</Catalog>
)
}

View File

@ -0,0 +1,147 @@
import Catalog from "../common/Catalog";
import { useEffect, useState } from "react";
import DataService from "../../services/DataService"
let headers = [
{label: "name", text: "Имя"},
{label: "genre", text: "Жанр"},
{label: "fullNames", text: "Актеры"}
]
export default function CatalogFilms() {
const url = "/films";
const [data, setData] = useState({
name: "",
genre: [],
fullNames: []
});
const [selectedData, setSelectedData] = useState({
genre: "",
actor: ""
});
const [genres, setGenres] = useState([]);
const [actors, setActors] = useState([]);
useEffect(() => {
let genre;
DataService.readAll("/genres").then(res => {
setGenres(res)
genre = res[0].name;
}).then(() => (
DataService.readAll("/actors")
)).then(res => {
setActors(res)
setSelectedData({genre, actor: res[0].name + " " + res[0].surname});
});
}, [])
function handleFormChange(e) {
console.log(e.target.value);
setData({ ...data, [e.target.id]: e.target.value })
}
function handleChangeSelected(e) {
setSelectedData({...selectedData, [e.target.id]: e.target.value});
}
function addGenre() {
for(let g of data.genre) {
if(g == selectedData.genre) return;
}
let temp = data.genre.slice(0);
temp.push(selectedData.genre);
setData({...data, genre: temp});
}
function addActor() {
for(let a of data.fullNames) {
if(a == selectedData.actor) return;
}
let temp = data.fullNames.slice(0);
temp.push(selectedData.actor);
setData({...data, fullNames: temp});
}
function deleteGenre(e) {
let genreName = e.target.previousSibling.textContent;
let temp = data.genre.filter(x => (x != genreName));
setData({...data, genre: temp})
}
function deleteActor(e) {
let actorName = e.target.previousSibling.textContent;
let temp = data.fullNames.filter(x => (x != actorName));
setData({...data, fullNames: temp})
}
function onAdd() {
setData({name: "", genre: [], fullNames: []});
}
function onChange(data) {
setData(data);
}
function validate(data) {
if(data.name === "") return false;
return true;
}
return (
<Catalog url={url} headers={headers} data={data} onAdd={onAdd} onChange={onChange} validate={validate}>
<div>
<div className="mb-3">
<label htmlFor="name" className="form-label">Название</label>
<input type="text" value={data.name} id="name" className="form-control" required autoComplete="off"
onChange={handleFormChange}/>
</div>
<select id="genre" className="form-select" required
value={selectedData.genre} onChange={handleChangeSelected}>
<option disabled value="">Укажите жанр</option>
{
genres.map(({name, id}) =>
<option key={id} value={name}>{name}</option>
)
}
</select>
{
data.genre.map(value => (
<div className="badge bg-secondary m-1" key={value}>
<span>{value}</span>
<button className="btn-close bg-danger m-1" onClick={deleteGenre}></button>
</div>
))
}
<br></br>
<button onClick={addGenre} className="btn btn-success">Добавить жанр</button>
<select id="actor" className="form-select" required
value={selectedData.actor} onChange={handleChangeSelected}>
<option disabled value="">Укажите актера</option>
{
actors.map(({name, surname, id}) =>
<option key={id} value={name + " " + surname}>{name + " " + surname}</option>
)
}
</select>
{
data.fullNames.map(value => (
<div className="badge bg-secondary m-1" key={value}>
<span>{value}</span>
<button className="btn-close bg-danger m-1" onClick={deleteActor}></button>
</div>
))
}
<br></br>
<button onClick={addActor} className="btn btn-success">Добавить актера</button>
</div>
</Catalog>
)
}

View File

@ -0,0 +1,46 @@
import Catalog from "../common/Catalog";
import { useEffect, useState } from "react";
import DataService from "../../services/DataService"
let headers = [
{label: "name", text: "Жанр"}
]
export default function CatalogGenres() {
const url = "/genres";
const [data, setData] = useState({
name: ""
});
const [genres, setGenres] = useState([]);
function handleFormChange(e) {
setData({ ...data, [e.target.id]: e.target.value })
}
function onAdd() {
setData({name: "", genre: genres[0]});
}
function onChange(data) {
setData(data);
}
function validate(data) {
if(data.name === "") return false;
return true;
}
return (
<Catalog url={url} headers={headers} data={data} onAdd={onAdd} onChange={onChange} validate={validate}>
<div className="mb-3">
<label htmlFor="name" className="form-label">Название</label>
<input type="text" value={data.name} id="name" className="form-control" required autoComplete="off"
onChange={handleFormChange}/>
</div>
</Catalog>
)
}

View File

@ -0,0 +1,104 @@
import { useEffect, useState } from "react";
import Table from "./Table";
import Toolbar from "./Toolbar";
import Modal from "./Modal";
import DataService from "../../services/DataService"
export default function Catalog(props) {
const [items, setItems] = useState([]);
const [visible, setVisible] = useState(false);
const [modalConfirm, setModalConfirm] = useState("");
const [modalHeader, setModalHeader] = useState("");
const [isEdit, setEdit] = useState(false);
let selectedItems = new Set();
useEffect(() => {
loadItems();
}, [])
function toggleSelect(id) {
if(selectedItems.has(id)) selectedItems.delete(id);
else selectedItems.add(id);
}
function loadItems() {
DataService.readAll(props.url)
.then(res => setItems(res));
}
function saveData() {
if(!props.validate(props.data)) return;
if(!isEdit) {
DataService.create(props.url, props.data).then(() => loadItems());
} else {
console.log(props.data);
DataService.update(props.url, props.data, props.data.id).then(() => loadItems());
}
}
function addHandler() {
setModalHeader("Добавление");
setModalConfirm("Добавить");
setEdit(false);
setVisible(true);
props.onAdd();
}
function changeHandler() {
if(!selectedItems.size) return;
if(!items.length) return;
let id = selectedItems.keys().next().value;
console.log(id);
let index = 0;
while(items[index].id !== id) {
index++;
}
props.onChange(items[index]);
selectedItems = new Set();
setModalHeader("Изменение");
setModalConfirm("Изменить");
setEdit(true);
setVisible(true);
}
function removeHandler() {
let queries = [];
for(let id of selectedItems.values()) {
queries.push(DataService.remove(props.url, id));
}
Promise.all(queries).then(() => {
loadItems()
});
}
function confirmHandler() {
saveData();
setVisible(false);
}
function closeHandler() {
setVisible(false);
}
return (
<div className="m-3">
<Toolbar addHandler={addHandler} changeHandler={changeHandler} removeHandler={removeHandler} />
<Table headers={props.headers} items={items} selected={selectedItems} toggleSelect={toggleSelect} selectable={true}/>
<Modal
visible={visible}
closeHandler={closeHandler}
header={modalHeader}
confirm={modalConfirm}
confirmHandler={confirmHandler}
>
{props.children}
</Modal>
</div>
)
}

View File

@ -0,0 +1,21 @@
.navbar__logo {
text-decoration: none;
margin-left: 30px;
}
.navbar__logo-text {
font-size: 30px;
text-decoration: none;
color: white;
}
.navbar__logo-text_first {
color: yellow;
}
body {
margin: 0;
background: linear-gradient(135deg, #8bf292, #a5ebb1) fixed;
min-height: 100vh;
position: relative;
}

View File

@ -0,0 +1,28 @@
import {NavLink} from "react-router-dom";
import "./Header.css";
export default function Header(props) {
return (
<header>
<nav className="navbar navbar-dark navbar-expand-lg bg-success">
<div className="container-fluid">
<NavLink className="navbar-brand" href="#">
<span className="navbar__logo-text navbar__logo-text_first">L</span><span className="navbar__logo-text navbar__logo-text_second">umer</span>
</NavLink>
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Переключатель навигации">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav">
{props.links.map(({id, text, path}) => (
<li key={id} className="nav-item">
<NavLink className="nav-link btn btn-success" aria-current="page" to={path}>{text}</NavLink>
</li>
))}
</ul>
</div>
</div>
</nav>
</header>
)
}

View File

@ -0,0 +1,11 @@
import {Link} from "react-router-dom";
export default function LinksList(props) {
return (
<div>
{props.items.map(({link, text}) => (
<Link key={link} to={link} className="btn btn-success">{text}</Link>
))}
</div>
)
}

View File

@ -0,0 +1,21 @@
export default function Modal(props) {
return (
<div className="modal fade show" tabIndex="-1" style={{ display: props.visible ? 'block' : 'none' }}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{props.header}</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Закрыть" onClick={props.closeHandler}></button>
</div>
<div className="modal-body">
{props.children}
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal" onClick={props.closeHandler}>Закрыть</button>
<button type="button" className="btn btn-primary" onClick={props.confirmHandler}>{props.confirm}</button>
</div>
</div>
</div>
</div>
)
}

View File

@ -0,0 +1,3 @@
.selected {
background: #2150de;
}

View File

@ -0,0 +1,41 @@
import { useState } from "react"
import "./Table.css";
export default function Table(props) {
const [tableUpdate, setTableUpdate] = useState(false);
function click(id) {
if(!props.selectable) return;
props.toggleSelect(id);
console.log(props.selected);
setTableUpdate(!tableUpdate);
}
return (
<table className="table table-hover">
<thead>
<tr>
<th>#</th>
{props.headers.map(({label, text}) => (
<th key={label}>{text}</th>
))}
</tr>
</thead>
<tbody>
{props.items.map((elem, index) => {
let trClass = "";
if(props.selectable && props.selected.has(elem.id)) trClass = "selected";
return (
<tr key={elem.id} onClick={click.bind(this, elem.id)} className={trClass}>
<td>{index + 1}</td>
{props.headers.map(({label}) => {
return <td key={label}>{(Array.isArray(elem[label])) ? elem[label].join(", ") : elem[label]}</td>
}
)}
</tr>
)})}
</tbody>
</table>
)
}

View File

@ -0,0 +1,9 @@
export default function Toolbar(props) {
return (
<div className="btn-group">
<button onClick={props.addHandler} className="btn btn-success">Добавить</button>
<button onClick={props.changeHandler} className="btn btn-info">Изменить</button>
<button onClick={props.removeHandler} className="btn btn-danger">Удалить</button>
</div>
)
}

View File

@ -0,0 +1,13 @@
import LinksList from "../common/LinksList";
export default function Catalogs() {
let items = [
{text: "фильмы", link: "catalogFilms"},,
{text: "актеры", link: "catalogActors"},
{text: "жанры", link: "catalogGenres"}
];
return (
<LinksList items={items}/>
)
}

View File

@ -0,0 +1,5 @@
.map__frame {
width: 90%;
height: 500px;
margin-bottom: 30px;
}

View File

@ -0,0 +1,12 @@
import "./Contacts.css";
export default function Contacts() {
return(
<main>
<section className="map">
<h2 className="text-white">Контакты</h2>
<iframe className="map__frame" title="map" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d158855.07580070102!2d-0.2470504135400737!3d51.52953198005434!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47d8a00baf21de75%3A0x52963a5addd52a99!2z0JvQvtC90LTQvtC9LCDQktC10LvQuNC60L7QsdGA0LjRgtCw0L3QuNGP!5e0!3m2!1sru!2sru!4v1664443841067!5m2!1sru!2sru" loading="lazy"/>
</section>
</main>
)
}

View File

@ -0,0 +1,47 @@
.player {
position: relative;
width: 80%;
height: 600px;
background: black;
margin: 10px auto;
}
.player:hover .player__menu {
opacity: 1;
}
.player__menu {
position: absolute;
width: 100%;
height: 60px;
bottom: 0;
background: gray;
display: flex;
align-items: center;
justify-content: space-around;
transition: 0.6s all ease;
opacity: 0;
}
.player__button {
width: 30px;
height: 30px;
background: transparent;
border: none;
padding: 0;
cursor: pointer;
}
.player__button:focus {
outline: none;
}
.player__button-img {
width: 100%;
}
.player__progress {
width: 85%;
height: 7px;
background: black;
}

View File

@ -0,0 +1,15 @@
import playIcon from "../../img/play.png";
import "./Film.css";
export default function Film() {
return (
<main>
<div class="player">
<div class="player__menu">
<button class="player__button"><img class="player__button-img" src={playIcon} alt=""/></button>
<div class="player__progress"></div>
</div>
</div>
</main>
)
}

View File

@ -0,0 +1,36 @@
import img1 from "../../img/1.jpg";
import img2 from "../../img/2.jpg";
import img3 from "../../img/3.jpg";
import img4 from "../../img/4.jpg";
import img5 from "../../img/5.jpg";
import Banner from "../Banner";
const images = [
{img: img1, id: 1},
{img: img2, id: 2},
{img: img3, id: 3},
{img: img4, id: 4},
{img: img5, id: 5}
];
export default function Films() {
return (
<main>
<section className="categories">
<h2 className="text-white">Категории</h2>
<div className="btn-group">
<button className="btn btn-success">Комедии</button>
<button className="btn btn-success">Драмы</button>
<button className="btn btn-success">Трилер</button>
</div>
</section>
<section className="banner">
<h2 className="text-white">Все фильмы</h2>
<Banner images={images}/>
</section>
</main>
)
}

View File

@ -0,0 +1,25 @@
import img1 from "../../img/1.jpg";
import img2 from "../../img/2.jpg";
import img3 from "../../img/3.jpg";
import img4 from "../../img/4.jpg";
import img5 from "../../img/5.jpg";
import Banner from "../Banner";
const images = [
{img: img1, id: 1},
{img: img2, id: 2},
{img: img3, id: 3},
{img: img4, id: 4},
{img: img5, id: 5}
];
export default function Home() {
return (
<main>
<section className="banner">
<h2 className="text-white">Популярные</h2>
<Banner images={images}/>
</section>
</main>
)
}

View File

@ -0,0 +1,11 @@
import LinksList from "../common/LinksList";
export default function Reports() {
let items = [
{text: "фильмы", link: "reportsFilms"},
];
return (
<LinksList items={items}/>
)
}

View File

@ -0,0 +1,50 @@
import { useEffect, useState } from "react";
import Table from "../common/Table";
import DataService from "../../services/DataService";
export default function ReportSelector(props) {
const [genres, setGenres] = useState([]);
const [currentGenre, setCurrentGenre] = useState("");
const [items, setItems] = useState([]);
useEffect(() => {
DataService.readAll("/genres").then(res => {
setGenres(res)
});
}, [])
useEffect(() => {
DataService.readAll(props.url).then(res => {
console.log(res);
setItems(res)
});
}, [props.url])
function changeGenre(e) {
setCurrentGenre(e.target.value);
}
console.log(props.url);
function click() {
props.formData(currentGenre);
}
return (
<div>
<div className="input-group mb-3">
<select className="form-select" onChange={changeGenre} value={currentGenre}>
<option disabled value="">Выберите группу</option>
{
genres.map(genre => (
<option key={genre.id} value={genre.genre}>{genre.genre}</option>
))
}
</select>
<button className="btn btn-outline-secondary" type="button" onClick={click}
>Сформировать</button>
</div >
<Table headers={props.headers} items={items} />
</div>
)
}

View File

@ -0,0 +1,26 @@
import Catalog from "../common/Catalog";
import { useEffect, useState } from "react";
import DataService from "../../services/DataService"
import Table from "../common/Table";
import ReportSelector from "./ReportSelector";
let headers = [
{label: "name", text: "Имя"},
{label: "genre", text: "Жанр"}
]
export default function ReportsFilms() {
const [url, setUrl] = useState("/films?genre=asdfasdfsadf");
function formData(genre) {
console.log(genre);
setUrl("/films?genre=" + genre);
}
return (
<ReportSelector headers={headers} url={url} formData={formData}/>
)
}

BIN
frontend/src/img/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
frontend/src/img/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
frontend/src/img/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
frontend/src/img/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
frontend/src/img/5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
frontend/src/img/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

13
frontend/src/index.css Normal file
View File

@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

17
frontend/src/index.js Normal file
View File

@ -0,0 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@ -0,0 +1,40 @@
export default class DataSirvice {
static urlPrefix = "http://localhost:8080";
static async readAll(url) {
let data = await fetch(this.urlPrefix + url);
let res = await data.json();
return res;
}
static create(url, data) {
return fetch(this.urlPrefix + url, {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
}
static update(url, data, id) {
console.log(this.urlPrefix + url + "/" + id)
console.log(data);
data.id = id;
return fetch(this.urlPrefix + url + "/" + id, {
method: "PATCH",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
}
static remove(url, id) {
return fetch(this.urlPrefix + url + "/" + id, {
method: "DELETE"
});
}
}

571
hs_err_pid8264.log Normal file
View File

@ -0,0 +1,571 @@
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 65536 bytes for Failed to commit metaspace.
# Possible reasons:
# The system is out of physical RAM or swap space
# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space
# Check if swap backing store is full
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize=
# JVM is running with Zero Based Compressed Oops mode in which the Java heap is
# placed in the first 32GB address space. The Java Heap base address is the
# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress
# to set the Java Heap base and to place the Java Heap above 32GB virtual address.
# This output file may be truncated or incomplete.
#
# Out of Memory Error (virtualSpaceNode.cpp:110), pid=8264, tid=4592
#
# JRE version: Java(TM) SE Runtime Environment (17.0.2+8) (build 17.0.2+8-LTS-86)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (17.0.2+8-LTS-86, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
--------------- S U M M A R Y ------------
Command Line: -XX:TieredStopAtLevel=1 -Dfile.encoding=windows-1251 -Duser.country=RU -Duser.language=ru -Duser.variant ru.ip.labs.labs.LabsApplication
Host: Intel(R) Core(TM) i3-8145U CPU @ 2.10GHz, 4 cores, 15G, Windows 10 , 64 bit Build 19041 (10.0.19041.2364)
Time: Mon Feb 20 15:05:21 2023 RTZ 2 (s 10 , 64 bit Build 19041 (10.0.19041.2364) elapsed time: 0.435306 seconds (0d 0h 0m 0s)
--------------- T H R E A D ---------------
Current thread (0x000001fe285b63d0): JavaThread "main" [_thread_in_vm, id=4592, stack(0x000000b0e1100000,0x000000b0e1200000)]
Stack: [0x000000b0e1100000,0x000000b0e1200000]
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [jvm.dll+0x670baa]
V [jvm.dll+0x7cfcb4]
V [jvm.dll+0x7d145e]
V [jvm.dll+0x7d1ac3]
V [jvm.dll+0x242bc5]
V [jvm.dll+0x7cbc5b]
V [jvm.dll+0x616966]
V [jvm.dll+0x1be3ee]
V [jvm.dll+0x6192a1]
V [jvm.dll+0x617306]
V [jvm.dll+0x2385a0]
V [jvm.dll+0x1e880d]
V [jvm.dll+0x1de251]
V [jvm.dll+0x537c30]
V [jvm.dll+0x74ad28]
V [jvm.dll+0x74ae14]
V [jvm.dll+0x408cc5]
V [jvm.dll+0x40ed18]
C [java.dll+0x17ec]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 826 java.lang.ClassLoader.defineClass1(Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;Ljava/lang/String;)Ljava/lang/Class; java.base@17.0.2 (0 bytes) @ 0x000001fe30176763 [0x000001fe301766a0+0x00000000000000c3]
J 840 c1 java.lang.ClassLoader.defineClass(Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class; java.base@17.0.2 (43 bytes) @ 0x000001fe3017bcec [0x000001fe3017bbe0+0x000000000000010c]
J 678 c1 jdk.internal.loader.BuiltinClassLoader.defineClass(Ljava/lang/String;Ljdk/internal/loader/Resource;)Ljava/lang/Class; java.base@17.0.2 (121 bytes) @ 0x000001fe30140c74 [0x000001fe301407a0+0x00000000000004d4]
J 666 c1 jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(Ljava/lang/String;)Ljava/lang/Class; java.base@17.0.2 (64 bytes) @ 0x000001fe30138944 [0x000001fe30138680+0x00000000000002c4]
J 360 c1 jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(Ljava/lang/String;Z)Ljava/lang/Class; java.base@17.0.2 (143 bytes) @ 0x000001fe3002b584 [0x000001fe3002b100+0x0000000000000484]
J 548 c1 jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; java.base@17.0.2 (40 bytes) @ 0x000001fe30106eac [0x000001fe30106d60+0x000000000000014c]
J 538 c1 java.lang.ClassLoader.loadClass(Ljava/lang/String;)Ljava/lang/Class; java.base@17.0.2 (7 bytes) @ 0x000001fe30103864 [0x000001fe30103820+0x0000000000000044]
v ~StubRoutines::call_stub
j org.springframework.core.convert.support.StreamConverter.<clinit>()V+2
v ~StubRoutines::call_stub
j org.springframework.core.convert.support.DefaultConversionService.addCollectionConverters(Lorg/springframework/core/convert/converter/ConverterRegistry;)V+188
j org.springframework.core.convert.support.DefaultConversionService.addDefaultConverters(Lorg/springframework/core/convert/converter/ConverterRegistry;)V+5
j org.springframework.boot.convert.ApplicationConversionService.configure(Lorg/springframework/format/FormatterRegistry;)V+1
j org.springframework.boot.convert.ApplicationConversionService.<init>(Lorg/springframework/util/StringValueResolver;Z)V+14
j org.springframework.boot.convert.ApplicationConversionService.<init>(Lorg/springframework/util/StringValueResolver;)V+3
j org.springframework.boot.convert.ApplicationConversionService.<init>()V+2
j org.springframework.boot.SpringApplication.configureEnvironment(Lorg/springframework/core/env/ConfigurableEnvironment;[Ljava/lang/String;)V+12
j org.springframework.boot.SpringApplication.prepareEnvironment(Lorg/springframework/boot/SpringApplicationRunListeners;Lorg/springframework/boot/DefaultBootstrapContext;Lorg/springframework/boot/ApplicationArguments;)Lorg/springframework/core/env/ConfigurableEnvironment;+15
j org.springframework.boot.SpringApplication.run([Ljava/lang/String;)Lorg/springframework/context/ConfigurableApplicationContext;+52
j org.springframework.boot.SpringApplication.run([Ljava/lang/Class;[Ljava/lang/String;)Lorg/springframework/context/ConfigurableApplicationContext;+9
j org.springframework.boot.SpringApplication.run(Ljava/lang/Class;[Ljava/lang/String;)Lorg/springframework/context/ConfigurableApplicationContext;+9
j ru.ip.labs.labs.LabsApplication.main([Ljava/lang/String;)V+3
v ~StubRoutines::call_stub
--------------- P R O C E S S ---------------
Threads class SMR info:
_java_thread_list=0x000001fe3f97be80, length=13, elements={
0x000001fe285b63d0, 0x000001fe3e83c990, 0x000001fe3e83d710, 0x000001fe3e854410,
0x000001fe3e856ce0, 0x000001fe3e8595b0, 0x000001fe3e87ae90, 0x000001fe3e8844a0,
0x000001fe3e88cdb0, 0x000001fe3f4e9870, 0x000001fe3f4f8e30, 0x000001fe3f4f62e0,
0x000001fe3f712060
}
Java Threads: ( => current thread )
=>0x000001fe285b63d0 JavaThread "main" [_thread_in_vm, id=4592, stack(0x000000b0e1100000,0x000000b0e1200000)]
0x000001fe3e83c990 JavaThread "Reference Handler" daemon [_thread_blocked, id=17388, stack(0x000000b0e1800000,0x000000b0e1900000)]
0x000001fe3e83d710 JavaThread "Finalizer" daemon [_thread_blocked, id=9572, stack(0x000000b0e1900000,0x000000b0e1a00000)]
0x000001fe3e854410 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=16104, stack(0x000000b0e1a00000,0x000000b0e1b00000)]
0x000001fe3e856ce0 JavaThread "Attach Listener" daemon [_thread_blocked, id=13168, stack(0x000000b0e1b00000,0x000000b0e1c00000)]
0x000001fe3e8595b0 JavaThread "Service Thread" daemon [_thread_blocked, id=2332, stack(0x000000b0e1c00000,0x000000b0e1d00000)]
0x000001fe3e87ae90 JavaThread "Monitor Deflation Thread" daemon [_thread_blocked, id=9668, stack(0x000000b0e1d00000,0x000000b0e1e00000)]
0x000001fe3e8844a0 JavaThread "C1 CompilerThread0" daemon [_thread_blocked, id=9472, stack(0x000000b0e1e00000,0x000000b0e1f00000)]
0x000001fe3e88cdb0 JavaThread "Sweeper thread" daemon [_thread_blocked, id=13320, stack(0x000000b0e1f00000,0x000000b0e2000000)]
0x000001fe3f4e9870 JavaThread "C1 CompilerThread1" daemon [_thread_blocked, id=4224, stack(0x000000b0e2000000,0x000000b0e2100000)]
0x000001fe3f4f8e30 JavaThread "Notification Thread" daemon [_thread_blocked, id=15036, stack(0x000000b0e2100000,0x000000b0e2200000)]
0x000001fe3f4f62e0 JavaThread "Common-Cleaner" daemon [_thread_blocked, id=12920, stack(0x000000b0e2300000,0x000000b0e2400000)]
0x000001fe3f712060 JavaThread "C1 CompilerThread2" daemon [_thread_blocked, id=17120, stack(0x000000b0e2400000,0x000000b0e2500000)]
Other Threads:
0x000001fe3e837e80 VMThread "VM Thread" [stack: 0x000000b0e1700000,0x000000b0e1800000] [id=10700]
0x000001fe2861e850 WatcherThread [stack: 0x000000b0e2200000,0x000000b0e2300000] [id=7428]
0x000001fe28603750 GCTaskThread "GC Thread#0" [stack: 0x000000b0e1200000,0x000000b0e1300000] [id=3184]
0x000001fe3fa47ba0 GCTaskThread "GC Thread#1" [stack: 0x000000b0e2500000,0x000000b0e2600000] [id=10876]
0x000001fe3fa4fea0 GCTaskThread "GC Thread#2" [stack: 0x000000b0e2600000,0x000000b0e2700000] [id=7940]
0x000001fe3fa50150 GCTaskThread "GC Thread#3" [stack: 0x000000b0e2700000,0x000000b0e2800000] [id=16468]
0x000001fe28616300 ConcurrentGCThread "G1 Main Marker" [stack: 0x000000b0e1300000,0x000000b0e1400000] [id=17368]
0x000001fe286173c0 ConcurrentGCThread "G1 Conc#0" [stack: 0x000000b0e1400000,0x000000b0e1500000] [id=14912]
0x000001fe3e7020c0 ConcurrentGCThread "G1 Refine#0" [stack: 0x000000b0e1500000,0x000000b0e1600000] [id=9096]
0x000001fe3fa31e10 ConcurrentGCThread "G1 Refine#1" [stack: 0x000000b0e2800000,0x000000b0e2900000] [id=16152]
0x000001fe3e7029f0 ConcurrentGCThread "G1 Service" [stack: 0x000000b0e1600000,0x000000b0e1700000] [id=12364]
Threads with active compile tasks:
VM state: not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event])
[0x000001fe285ae5d0] Metaspace_lock - owner thread: 0x000001fe285b63d0
Heap address: 0x0000000702c00000, size: 4052 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
CDS archive(s) mapped at: [0x0000000800000000-0x0000000800bc0000-0x0000000800bc0000), size 12320768, SharedBaseAddress: 0x0000000800000000, ArchiveRelocationMode: 0.
Compressed class space mapped at: 0x0000000800c00000-0x0000000840c00000, reserved size: 1073741824
Narrow klass base: 0x0000000800000000, Narrow klass shift: 0, Narrow klass range: 0x100000000
GC Precious Log:
CPUs: 4 total, 4 available
Memory: 16205M
Large Page Support: Disabled
NUMA Support: Disabled
Compressed Oops: Enabled (Zero based)
Heap Region Size: 2M
Heap Min Capacity: 8M
Heap Initial Capacity: 254M
Heap Max Capacity: 4052M
Pre-touch: Disabled
Parallel Workers: 4
Concurrent Workers: 1
Concurrent Refinement Workers: 4
Periodic GC: Disabled
Heap:
garbage-first heap total 260096K, used 5595K [0x0000000702c00000, 0x0000000800000000)
region size 2048K, 3 young (6144K), 1 survivors (2048K)
Metaspace used 3793K, committed 3904K, reserved 1056768K
class space used 487K, committed 576K, reserved 1048576K
Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, OA=open archive, CA=closed archive, TAMS=top-at-mark-start (previous, next)
| 0|0x0000000702c00000, 0x0000000702d76e00, 0x0000000702e00000| 73%| O| |TAMS 0x0000000702c00000, 0x0000000702c00000| Untracked
| 1|0x0000000702e00000, 0x0000000702e00000, 0x0000000703000000| 0%| F| |TAMS 0x0000000702e00000, 0x0000000702e00000| Untracked
| 2|0x0000000703000000, 0x0000000703000000, 0x0000000703200000| 0%| F| |TAMS 0x0000000703000000, 0x0000000703000000| Untracked
| 3|0x0000000703200000, 0x0000000703200000, 0x0000000703400000| 0%| F| |TAMS 0x0000000703200000, 0x0000000703200000| Untracked
| 4|0x0000000703400000, 0x0000000703400000, 0x0000000703600000| 0%| F| |TAMS 0x0000000703400000, 0x0000000703400000| Untracked
| 5|0x0000000703600000, 0x0000000703600000, 0x0000000703800000| 0%| F| |TAMS 0x0000000703600000, 0x0000000703600000| Untracked
| 6|0x0000000703800000, 0x0000000703800000, 0x0000000703a00000| 0%| F| |TAMS 0x0000000703800000, 0x0000000703800000| Untracked
| 7|0x0000000703a00000, 0x0000000703a00000, 0x0000000703c00000| 0%| F| |TAMS 0x0000000703a00000, 0x0000000703a00000| Untracked
| 8|0x0000000703c00000, 0x0000000703c00000, 0x0000000703e00000| 0%| F| |TAMS 0x0000000703c00000, 0x0000000703c00000| Untracked
| 9|0x0000000703e00000, 0x0000000703e00000, 0x0000000704000000| 0%| F| |TAMS 0x0000000703e00000, 0x0000000703e00000| Untracked
| 10|0x0000000704000000, 0x0000000704000000, 0x0000000704200000| 0%| F| |TAMS 0x0000000704000000, 0x0000000704000000| Untracked
| 11|0x0000000704200000, 0x0000000704200000, 0x0000000704400000| 0%| F| |TAMS 0x0000000704200000, 0x0000000704200000| Untracked
| 12|0x0000000704400000, 0x0000000704400000, 0x0000000704600000| 0%| F| |TAMS 0x0000000704400000, 0x0000000704400000| Untracked
| 13|0x0000000704600000, 0x0000000704600000, 0x0000000704800000| 0%| F| |TAMS 0x0000000704600000, 0x0000000704600000| Untracked
| 14|0x0000000704800000, 0x0000000704800000, 0x0000000704a00000| 0%| F| |TAMS 0x0000000704800000, 0x0000000704800000| Untracked
| 15|0x0000000704a00000, 0x0000000704a00000, 0x0000000704c00000| 0%| F| |TAMS 0x0000000704a00000, 0x0000000704a00000| Untracked
| 16|0x0000000704c00000, 0x0000000704c00000, 0x0000000704e00000| 0%| F| |TAMS 0x0000000704c00000, 0x0000000704c00000| Untracked
| 17|0x0000000704e00000, 0x0000000704e00000, 0x0000000705000000| 0%| F| |TAMS 0x0000000704e00000, 0x0000000704e00000| Untracked
| 18|0x0000000705000000, 0x0000000705000000, 0x0000000705200000| 0%| F| |TAMS 0x0000000705000000, 0x0000000705000000| Untracked
| 19|0x0000000705200000, 0x0000000705200000, 0x0000000705400000| 0%| F| |TAMS 0x0000000705200000, 0x0000000705200000| Untracked
| 20|0x0000000705400000, 0x0000000705400000, 0x0000000705600000| 0%| F| |TAMS 0x0000000705400000, 0x0000000705400000| Untracked
| 21|0x0000000705600000, 0x0000000705600000, 0x0000000705800000| 0%| F| |TAMS 0x0000000705600000, 0x0000000705600000| Untracked
| 22|0x0000000705800000, 0x0000000705800000, 0x0000000705a00000| 0%| F| |TAMS 0x0000000705800000, 0x0000000705800000| Untracked
| 23|0x0000000705a00000, 0x0000000705a00000, 0x0000000705c00000| 0%| F| |TAMS 0x0000000705a00000, 0x0000000705a00000| Untracked
| 24|0x0000000705c00000, 0x0000000705c00000, 0x0000000705e00000| 0%| F| |TAMS 0x0000000705c00000, 0x0000000705c00000| Untracked
| 25|0x0000000705e00000, 0x0000000705e00000, 0x0000000706000000| 0%| F| |TAMS 0x0000000705e00000, 0x0000000705e00000| Untracked
| 26|0x0000000706000000, 0x0000000706000000, 0x0000000706200000| 0%| F| |TAMS 0x0000000706000000, 0x0000000706000000| Untracked
| 27|0x0000000706200000, 0x0000000706200000, 0x0000000706400000| 0%| F| |TAMS 0x0000000706200000, 0x0000000706200000| Untracked
| 28|0x0000000706400000, 0x0000000706400000, 0x0000000706600000| 0%| F| |TAMS 0x0000000706400000, 0x0000000706400000| Untracked
| 29|0x0000000706600000, 0x0000000706600000, 0x0000000706800000| 0%| F| |TAMS 0x0000000706600000, 0x0000000706600000| Untracked
| 30|0x0000000706800000, 0x0000000706800000, 0x0000000706a00000| 0%| F| |TAMS 0x0000000706800000, 0x0000000706800000| Untracked
| 31|0x0000000706a00000, 0x0000000706a00000, 0x0000000706c00000| 0%| F| |TAMS 0x0000000706a00000, 0x0000000706a00000| Untracked
| 32|0x0000000706c00000, 0x0000000706c00000, 0x0000000706e00000| 0%| F| |TAMS 0x0000000706c00000, 0x0000000706c00000| Untracked
| 33|0x0000000706e00000, 0x0000000706e00000, 0x0000000707000000| 0%| F| |TAMS 0x0000000706e00000, 0x0000000706e00000| Untracked
| 34|0x0000000707000000, 0x0000000707000000, 0x0000000707200000| 0%| F| |TAMS 0x0000000707000000, 0x0000000707000000| Untracked
| 35|0x0000000707200000, 0x0000000707200000, 0x0000000707400000| 0%| F| |TAMS 0x0000000707200000, 0x0000000707200000| Untracked
| 36|0x0000000707400000, 0x0000000707400000, 0x0000000707600000| 0%| F| |TAMS 0x0000000707400000, 0x0000000707400000| Untracked
| 37|0x0000000707600000, 0x0000000707600000, 0x0000000707800000| 0%| F| |TAMS 0x0000000707600000, 0x0000000707600000| Untracked
| 38|0x0000000707800000, 0x0000000707800000, 0x0000000707a00000| 0%| F| |TAMS 0x0000000707800000, 0x0000000707800000| Untracked
| 39|0x0000000707a00000, 0x0000000707a00000, 0x0000000707c00000| 0%| F| |TAMS 0x0000000707a00000, 0x0000000707a00000| Untracked
| 40|0x0000000707c00000, 0x0000000707c00000, 0x0000000707e00000| 0%| F| |TAMS 0x0000000707c00000, 0x0000000707c00000| Untracked
| 41|0x0000000707e00000, 0x0000000707e00000, 0x0000000708000000| 0%| F| |TAMS 0x0000000707e00000, 0x0000000707e00000| Untracked
| 42|0x0000000708000000, 0x0000000708000000, 0x0000000708200000| 0%| F| |TAMS 0x0000000708000000, 0x0000000708000000| Untracked
| 43|0x0000000708200000, 0x0000000708200000, 0x0000000708400000| 0%| F| |TAMS 0x0000000708200000, 0x0000000708200000| Untracked
| 44|0x0000000708400000, 0x0000000708400000, 0x0000000708600000| 0%| F| |TAMS 0x0000000708400000, 0x0000000708400000| Untracked
| 45|0x0000000708600000, 0x0000000708600000, 0x0000000708800000| 0%| F| |TAMS 0x0000000708600000, 0x0000000708600000| Untracked
| 46|0x0000000708800000, 0x0000000708800000, 0x0000000708a00000| 0%| F| |TAMS 0x0000000708800000, 0x0000000708800000| Untracked
| 47|0x0000000708a00000, 0x0000000708a00000, 0x0000000708c00000| 0%| F| |TAMS 0x0000000708a00000, 0x0000000708a00000| Untracked
| 48|0x0000000708c00000, 0x0000000708c00000, 0x0000000708e00000| 0%| F| |TAMS 0x0000000708c00000, 0x0000000708c00000| Untracked
| 49|0x0000000708e00000, 0x0000000708e00000, 0x0000000709000000| 0%| F| |TAMS 0x0000000708e00000, 0x0000000708e00000| Untracked
| 50|0x0000000709000000, 0x0000000709000000, 0x0000000709200000| 0%| F| |TAMS 0x0000000709000000, 0x0000000709000000| Untracked
| 51|0x0000000709200000, 0x0000000709200000, 0x0000000709400000| 0%| F| |TAMS 0x0000000709200000, 0x0000000709200000| Untracked
| 52|0x0000000709400000, 0x0000000709400000, 0x0000000709600000| 0%| F| |TAMS 0x0000000709400000, 0x0000000709400000| Untracked
| 53|0x0000000709600000, 0x0000000709600000, 0x0000000709800000| 0%| F| |TAMS 0x0000000709600000, 0x0000000709600000| Untracked
| 54|0x0000000709800000, 0x0000000709800000, 0x0000000709a00000| 0%| F| |TAMS 0x0000000709800000, 0x0000000709800000| Untracked
| 55|0x0000000709a00000, 0x0000000709a00000, 0x0000000709c00000| 0%| F| |TAMS 0x0000000709a00000, 0x0000000709a00000| Untracked
| 56|0x0000000709c00000, 0x0000000709c00000, 0x0000000709e00000| 0%| F| |TAMS 0x0000000709c00000, 0x0000000709c00000| Untracked
| 57|0x0000000709e00000, 0x0000000709e00000, 0x000000070a000000| 0%| F| |TAMS 0x0000000709e00000, 0x0000000709e00000| Untracked
| 58|0x000000070a000000, 0x000000070a000000, 0x000000070a200000| 0%| F| |TAMS 0x000000070a000000, 0x000000070a000000| Untracked
| 59|0x000000070a200000, 0x000000070a200000, 0x000000070a400000| 0%| F| |TAMS 0x000000070a200000, 0x000000070a200000| Untracked
| 60|0x000000070a400000, 0x000000070a400000, 0x000000070a600000| 0%| F| |TAMS 0x000000070a400000, 0x000000070a400000| Untracked
| 61|0x000000070a600000, 0x000000070a600000, 0x000000070a800000| 0%| F| |TAMS 0x000000070a600000, 0x000000070a600000| Untracked
| 62|0x000000070a800000, 0x000000070a800000, 0x000000070aa00000| 0%| F| |TAMS 0x000000070a800000, 0x000000070a800000| Untracked
| 63|0x000000070aa00000, 0x000000070aa00000, 0x000000070ac00000| 0%| F| |TAMS 0x000000070aa00000, 0x000000070aa00000| Untracked
| 64|0x000000070ac00000, 0x000000070ac00000, 0x000000070ae00000| 0%| F| |TAMS 0x000000070ac00000, 0x000000070ac00000| Untracked
| 65|0x000000070ae00000, 0x000000070ae00000, 0x000000070b000000| 0%| F| |TAMS 0x000000070ae00000, 0x000000070ae00000| Untracked
| 66|0x000000070b000000, 0x000000070b000000, 0x000000070b200000| 0%| F| |TAMS 0x000000070b000000, 0x000000070b000000| Untracked
| 67|0x000000070b200000, 0x000000070b200000, 0x000000070b400000| 0%| F| |TAMS 0x000000070b200000, 0x000000070b200000| Untracked
| 68|0x000000070b400000, 0x000000070b400000, 0x000000070b600000| 0%| F| |TAMS 0x000000070b400000, 0x000000070b400000| Untracked
| 69|0x000000070b600000, 0x000000070b600000, 0x000000070b800000| 0%| F| |TAMS 0x000000070b600000, 0x000000070b600000| Untracked
| 70|0x000000070b800000, 0x000000070b800000, 0x000000070ba00000| 0%| F| |TAMS 0x000000070b800000, 0x000000070b800000| Untracked
| 71|0x000000070ba00000, 0x000000070ba00000, 0x000000070bc00000| 0%| F| |TAMS 0x000000070ba00000, 0x000000070ba00000| Untracked
| 72|0x000000070bc00000, 0x000000070bc00000, 0x000000070be00000| 0%| F| |TAMS 0x000000070bc00000, 0x000000070bc00000| Untracked
| 73|0x000000070be00000, 0x000000070be00000, 0x000000070c000000| 0%| F| |TAMS 0x000000070be00000, 0x000000070be00000| Untracked
| 74|0x000000070c000000, 0x000000070c000000, 0x000000070c200000| 0%| F| |TAMS 0x000000070c000000, 0x000000070c000000| Untracked
| 75|0x000000070c200000, 0x000000070c200000, 0x000000070c400000| 0%| F| |TAMS 0x000000070c200000, 0x000000070c200000| Untracked
| 76|0x000000070c400000, 0x000000070c400000, 0x000000070c600000| 0%| F| |TAMS 0x000000070c400000, 0x000000070c400000| Untracked
| 77|0x000000070c600000, 0x000000070c600000, 0x000000070c800000| 0%| F| |TAMS 0x000000070c600000, 0x000000070c600000| Untracked
| 78|0x000000070c800000, 0x000000070c800000, 0x000000070ca00000| 0%| F| |TAMS 0x000000070c800000, 0x000000070c800000| Untracked
| 79|0x000000070ca00000, 0x000000070ca00000, 0x000000070cc00000| 0%| F| |TAMS 0x000000070ca00000, 0x000000070ca00000| Untracked
| 80|0x000000070cc00000, 0x000000070cc00000, 0x000000070ce00000| 0%| F| |TAMS 0x000000070cc00000, 0x000000070cc00000| Untracked
| 81|0x000000070ce00000, 0x000000070ce00000, 0x000000070d000000| 0%| F| |TAMS 0x000000070ce00000, 0x000000070ce00000| Untracked
| 82|0x000000070d000000, 0x000000070d000000, 0x000000070d200000| 0%| F| |TAMS 0x000000070d000000, 0x000000070d000000| Untracked
| 83|0x000000070d200000, 0x000000070d200000, 0x000000070d400000| 0%| F| |TAMS 0x000000070d200000, 0x000000070d200000| Untracked
| 84|0x000000070d400000, 0x000000070d400000, 0x000000070d600000| 0%| F| |TAMS 0x000000070d400000, 0x000000070d400000| Untracked
| 85|0x000000070d600000, 0x000000070d600000, 0x000000070d800000| 0%| F| |TAMS 0x000000070d600000, 0x000000070d600000| Untracked
| 86|0x000000070d800000, 0x000000070d800000, 0x000000070da00000| 0%| F| |TAMS 0x000000070d800000, 0x000000070d800000| Untracked
| 87|0x000000070da00000, 0x000000070da00000, 0x000000070dc00000| 0%| F| |TAMS 0x000000070da00000, 0x000000070da00000| Untracked
| 88|0x000000070dc00000, 0x000000070dc00000, 0x000000070de00000| 0%| F| |TAMS 0x000000070dc00000, 0x000000070dc00000| Untracked
| 89|0x000000070de00000, 0x000000070de00000, 0x000000070e000000| 0%| F| |TAMS 0x000000070de00000, 0x000000070de00000| Untracked
| 90|0x000000070e000000, 0x000000070e000000, 0x000000070e200000| 0%| F| |TAMS 0x000000070e000000, 0x000000070e000000| Untracked
| 91|0x000000070e200000, 0x000000070e200000, 0x000000070e400000| 0%| F| |TAMS 0x000000070e200000, 0x000000070e200000| Untracked
| 92|0x000000070e400000, 0x000000070e400000, 0x000000070e600000| 0%| F| |TAMS 0x000000070e400000, 0x000000070e400000| Untracked
| 93|0x000000070e600000, 0x000000070e600000, 0x000000070e800000| 0%| F| |TAMS 0x000000070e600000, 0x000000070e600000| Untracked
| 94|0x000000070e800000, 0x000000070e800000, 0x000000070ea00000| 0%| F| |TAMS 0x000000070e800000, 0x000000070e800000| Untracked
| 95|0x000000070ea00000, 0x000000070ea00000, 0x000000070ec00000| 0%| F| |TAMS 0x000000070ea00000, 0x000000070ea00000| Untracked
| 96|0x000000070ec00000, 0x000000070ec00000, 0x000000070ee00000| 0%| F| |TAMS 0x000000070ec00000, 0x000000070ec00000| Untracked
| 97|0x000000070ee00000, 0x000000070ee00000, 0x000000070f000000| 0%| F| |TAMS 0x000000070ee00000, 0x000000070ee00000| Untracked
| 98|0x000000070f000000, 0x000000070f000000, 0x000000070f200000| 0%| F| |TAMS 0x000000070f000000, 0x000000070f000000| Untracked
| 99|0x000000070f200000, 0x000000070f200000, 0x000000070f400000| 0%| F| |TAMS 0x000000070f200000, 0x000000070f200000| Untracked
| 100|0x000000070f400000, 0x000000070f400000, 0x000000070f600000| 0%| F| |TAMS 0x000000070f400000, 0x000000070f400000| Untracked
| 101|0x000000070f600000, 0x000000070f600000, 0x000000070f800000| 0%| F| |TAMS 0x000000070f600000, 0x000000070f600000| Untracked
| 102|0x000000070f800000, 0x000000070f800000, 0x000000070fa00000| 0%| F| |TAMS 0x000000070f800000, 0x000000070f800000| Untracked
| 103|0x000000070fa00000, 0x000000070fa00000, 0x000000070fc00000| 0%| F| |TAMS 0x000000070fa00000, 0x000000070fa00000| Untracked
| 104|0x000000070fc00000, 0x000000070fc00000, 0x000000070fe00000| 0%| F| |TAMS 0x000000070fc00000, 0x000000070fc00000| Untracked
| 105|0x000000070fe00000, 0x000000070fe00000, 0x0000000710000000| 0%| F| |TAMS 0x000000070fe00000, 0x000000070fe00000| Untracked
| 106|0x0000000710000000, 0x0000000710000000, 0x0000000710200000| 0%| F| |TAMS 0x0000000710000000, 0x0000000710000000| Untracked
| 107|0x0000000710200000, 0x0000000710200000, 0x0000000710400000| 0%| F| |TAMS 0x0000000710200000, 0x0000000710200000| Untracked
| 108|0x0000000710400000, 0x0000000710400000, 0x0000000710600000| 0%| F| |TAMS 0x0000000710400000, 0x0000000710400000| Untracked
| 109|0x0000000710600000, 0x0000000710600000, 0x0000000710800000| 0%| F| |TAMS 0x0000000710600000, 0x0000000710600000| Untracked
| 110|0x0000000710800000, 0x0000000710800000, 0x0000000710a00000| 0%| F| |TAMS 0x0000000710800000, 0x0000000710800000| Untracked
| 111|0x0000000710a00000, 0x0000000710a00000, 0x0000000710c00000| 0%| F| |TAMS 0x0000000710a00000, 0x0000000710a00000| Untracked
| 112|0x0000000710c00000, 0x0000000710c00000, 0x0000000710e00000| 0%| F| |TAMS 0x0000000710c00000, 0x0000000710c00000| Untracked
| 113|0x0000000710e00000, 0x0000000710e00000, 0x0000000711000000| 0%| F| |TAMS 0x0000000710e00000, 0x0000000710e00000| Untracked
| 114|0x0000000711000000, 0x0000000711000000, 0x0000000711200000| 0%| F| |TAMS 0x0000000711000000, 0x0000000711000000| Untracked
| 115|0x0000000711200000, 0x0000000711200000, 0x0000000711400000| 0%| F| |TAMS 0x0000000711200000, 0x0000000711200000| Untracked
| 116|0x0000000711400000, 0x0000000711400000, 0x0000000711600000| 0%| F| |TAMS 0x0000000711400000, 0x0000000711400000| Untracked
| 117|0x0000000711600000, 0x0000000711600000, 0x0000000711800000| 0%| F| |TAMS 0x0000000711600000, 0x0000000711600000| Untracked
| 118|0x0000000711800000, 0x0000000711800000, 0x0000000711a00000| 0%| F| |TAMS 0x0000000711800000, 0x0000000711800000| Untracked
| 119|0x0000000711a00000, 0x0000000711a00000, 0x0000000711c00000| 0%| F| |TAMS 0x0000000711a00000, 0x0000000711a00000| Untracked
| 120|0x0000000711c00000, 0x0000000711e00000, 0x0000000711e00000|100%| S|CS|TAMS 0x0000000711c00000, 0x0000000711c00000| Complete
| 121|0x0000000711e00000, 0x0000000711e00000, 0x0000000712000000| 0%| F| |TAMS 0x0000000711e00000, 0x0000000711e00000| Untracked
| 122|0x0000000712000000, 0x0000000712000000, 0x0000000712200000| 0%| F| |TAMS 0x0000000712000000, 0x0000000712000000| Untracked
| 123|0x0000000712200000, 0x0000000712200000, 0x0000000712400000| 0%| F| |TAMS 0x0000000712200000, 0x0000000712200000| Untracked
| 124|0x0000000712400000, 0x0000000712400000, 0x0000000712600000| 0%| F| |TAMS 0x0000000712400000, 0x0000000712400000| Untracked
| 125|0x0000000712600000, 0x00000007127f4368, 0x0000000712800000| 97%| E| |TAMS 0x0000000712600000, 0x0000000712600000| Complete
| 126|0x0000000712800000, 0x0000000712a00000, 0x0000000712a00000|100%| E|CS|TAMS 0x0000000712800000, 0x0000000712800000| Complete
Card table byte_map: [0x000001fe33600000,0x000001fe33df0000] _byte_map_base: 0x000001fe2fdea000
Marking Bits (Prev, Next): (CMBitMap*) 0x000001fe28605c90, (CMBitMap*) 0x000001fe28605cd0
Prev Bits: [0x000001fe345e0000, 0x000001fe38530000)
Next Bits: [0x000001fe38530000, 0x000001fe3c480000)
Polling page: 0x000001fe27d90000
Metaspace:
Usage:
Non-class: 3.23 MB used.
Class: 487.02 KB used.
Both: 3.70 MB used.
Virtual space:
Non-class space: 8.00 MB reserved, 3.25 MB ( 41%) committed, 1 nodes.
Class space: 1.00 GB reserved, 576.00 KB ( <1%) committed, 1 nodes.
Both: 1.01 GB reserved, 3.81 MB ( <1%) committed.
Chunk freelists:
Non-Class: 2.11 MB
Class: 3.45 MB
Both: 5.56 MB
MaxMetaspaceSize: unlimited
CompressedClassSpaceSize: 1.00 GB
Initial GC threshold: 21.00 MB
Current GC threshold: 21.00 MB
CDS: on
MetaspaceReclaimPolicy: balanced
- commit_granule_bytes: 65536.
- commit_granule_words: 8192.
- virtual_space_node_default_size: 1048576.
- enlarge_chunks_in_place: 1.
- new_chunks_are_fully_committed: 0.
- uncommit_free_chunks: 1.
- use_allocation_guard: 0.
- handle_deallocations: 1.
Internal statistics:
num_allocs_failed_limit: 0.
num_arena_births: 34.
num_arena_deaths: 0.
num_vsnodes_births: 2.
num_vsnodes_deaths: 0.
num_space_committed: 61.
num_space_uncommitted: 0.
num_chunks_returned_to_freelist: 0.
num_chunks_taken_from_freelist: 146.
num_chunk_merges: 0.
num_chunk_splits: 88.
num_chunks_enlarged: 67.
num_purges: 0.
num_inconsistent_stats: 0.
CodeCache: size=49152Kb used=3545Kb max_used=3545Kb free=45606Kb
bounds [0x000001fe2fe10000, 0x000001fe30190000, 0x000001fe32e10000]
total_blobs=1275 nmethods=866 adapters=335
compilation: enabled
stopped_count=0, restarted_count=0
full_count=0
Compilation events (20 events):
Event: 0.421 Thread 0x000001fe3e8844a0 nmethod 856 0x000001fe30182f90 code [0x000001fe30183120, 0x000001fe30183258]
Event: 0.421 Thread 0x000001fe3f712060 nmethod 855 0x000001fe30183310 code [0x000001fe301834a0, 0x000001fe30183638]
Event: 0.422 Thread 0x000001fe3f4e9870 857 1 java.util.Objects::hashCode (13 bytes)
Event: 0.423 Thread 0x000001fe3f4e9870 nmethod 857 0x000001fe30183710 code [0x000001fe301838a0, 0x000001fe301839a8]
Event: 0.423 Thread 0x000001fe3e8844a0 858 1 sun.reflect.generics.visitor.Reifier::getFactory (5 bytes)
Event: 0.423 Thread 0x000001fe3f4e9870 859 ! 1 org.springframework.util.ConcurrentReferenceHashMap$Segment::clear (69 bytes)
Event: 0.423 Thread 0x000001fe3e8844a0 nmethod 858 0x000001fe30183a10 code [0x000001fe30183ba0, 0x000001fe30183c78]
Event: 0.424 Thread 0x000001fe3e8844a0 860 1 org.springframework.core.ResolvableType::resolve (5 bytes)
Event: 0.424 Thread 0x000001fe3f712060 861 1 java.util.ArrayList::<init> (61 bytes)
Event: 0.424 Thread 0x000001fe3e8844a0 nmethod 860 0x000001fe30183d10 code [0x000001fe30183ea0, 0x000001fe30183f78]
Event: 0.424 Thread 0x000001fe3f4e9870 nmethod 859 0x000001fe30184010 code [0x000001fe30184220, 0x000001fe301846e8]
Event: 0.424 Thread 0x000001fe3e8844a0 862 1 java.util.concurrent.locks.AbstractOwnableSynchronizer::setExclusiveOwnerThread (6 bytes)
Event: 0.424 Thread 0x000001fe3f4e9870 863 1 java.lang.Class::cast (27 bytes)
Event: 0.424 Thread 0x000001fe3f712060 nmethod 861 0x000001fe30184a10 code [0x000001fe30184c00, 0x000001fe30185198]
Event: 0.424 Thread 0x000001fe3e8844a0 nmethod 862 0x000001fe30185390 code [0x000001fe30185520, 0x000001fe30185638]
Event: 0.424 Thread 0x000001fe3f4e9870 nmethod 863 0x000001fe30185a90 code [0x000001fe30185c40, 0x000001fe30185df8]
Event: 0.426 Thread 0x000001fe3e8844a0 865 1 sun.reflect.generics.tree.SimpleClassTypeSignature::getTypeArguments (5 bytes)
Event: 0.426 Thread 0x000001fe3e8844a0 nmethod 865 0x000001fe30185f10 code [0x000001fe301860a0, 0x000001fe30186178]
Event: 0.429 Thread 0x000001fe3e8844a0 866 1 java.util.Collections$1::hasNext (5 bytes)
Event: 0.430 Thread 0x000001fe3e8844a0 nmethod 866 0x000001fe30186210 code [0x000001fe301863a0, 0x000001fe30186478]
GC Heap History (2 events):
Event: 0.326 GC heap before
{Heap before GC invocations=0 (full 0):
garbage-first heap total 260096K, used 10240K [0x0000000702c00000, 0x0000000800000000)
region size 2048K, 6 young (12288K), 0 survivors (0K)
Metaspace used 2827K, committed 3008K, reserved 1056768K
class space used 347K, committed 448K, reserved 1048576K
}
Event: 0.329 GC heap after
{Heap after GC invocations=1 (full 0):
garbage-first heap total 260096K, used 3547K [0x0000000702c00000, 0x0000000800000000)
region size 2048K, 1 young (2048K), 1 survivors (2048K)
Metaspace used 2827K, committed 3008K, reserved 1056768K
class space used 347K, committed 448K, reserved 1048576K
}
Deoptimization events (2 events):
Event: 0.333 Thread 0x000001fe285b63d0 DEOPT PACKING pc=0x000001fe3014a801 sp=0x000000b0e11fd2c0
Event: 0.333 Thread 0x000001fe285b63d0 DEOPT UNPACKING pc=0x000001fe2fe62b43 sp=0x000000b0e11fc730 mode 3
Classes unloaded (0 events):
No events
Classes redefined (0 events):
No events
Internal exceptions (12 events):
Event: 0.174 Thread 0x000001fe285b63d0 Exception <a 'java/lang/ClassNotFoundException'{0x0000000712542060}: javax/smartcardio/CardPermission> (0x0000000712542060)
thrown [t:\workspace\open\src\hotspot\share\classfile\systemDictionary.cpp, line 256]
Event: 0.176 Thread 0x000001fe285b63d0 Exception <a 'java/io/FileNotFoundException'{0x0000000712550b48}> (0x0000000712550b48)
thrown [t:\workspace\open\src\hotspot\share\prims\jni.cpp, line 516]
Event: 0.261 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x0000000712114910}: 'java.lang.Object java.lang.invoke.DirectMethodHandle$Holder.invokeSpecialIFC(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)'> (0x0000000712114910)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.278 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x00000007121c6f90}: 'int java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(java.lang.Object, java.lang.Object)'> (0x00000007121c6f90)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.322 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x0000000711fcd8f0}: 'int java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(java.lang.Object, java.lang.Object, java.lang.Object)'> (0x0000000711fcd8f0)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.332 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x0000000712828620}: 'java.lang.Object java.lang.invoke.DirectMethodHandle$Holder.newInvokeSpecial(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)'> (0x0000000712828620)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.338 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x00000007128666a8}: 'java.lang.Object java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(java.lang.Object, java.lang.Object, java.lang.Object)'> (0x00000007128666a8)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.342 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x00000007128c9608}: 'void java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(java.lang.Object, java.lang.Object, java.lang.Object)'> (0x00000007128c9608)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.377 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x0000000712642430}: 'java.lang.Object java.lang.invoke.DirectMethodHandle$Holder.invokeInterface(java.lang.Object, java.lang.Object, java.lang.Object)'> (0x0000000712642430)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.378 Thread 0x000001fe285b63d0 Exception <a 'java/lang/IncompatibleClassChangeError'{0x0000000712645850}: Found class java.lang.Object, but interface was expected> (0x0000000712645850)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 833]
Event: 0.394 Thread 0x000001fe285b63d0 Exception <a 'java/lang/NoSuchMethodError'{0x00000007126bce58}: 'java.lang.Object java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(java.lang.Object)'> (0x00000007126bce58)
thrown [t:\workspace\open\src\hotspot\share\interpreter\linkResolver.cpp, line 766]
Event: 0.400 Thread 0x000001fe285b63d0 Exception <a 'sun/nio/fs/WindowsException'{0x00000007126d1ca8}> (0x00000007126d1ca8)
thrown [t:\workspace\open\src\hotspot\share\prims\jni.cpp, line 516]
VM Operations (10 events):
Event: 0.083 Executing VM operation: HandshakeAllThreads
Event: 0.083 Executing VM operation: HandshakeAllThreads done
Event: 0.240 Executing VM operation: HandshakeAllThreads
Event: 0.240 Executing VM operation: HandshakeAllThreads done
Event: 0.254 Executing VM operation: HandshakeAllThreads
Event: 0.254 Executing VM operation: HandshakeAllThreads done
Event: 0.326 Executing VM operation: G1CollectForAllocation
Event: 0.329 Executing VM operation: G1CollectForAllocation done
Event: 0.401 Executing VM operation: HandshakeAllThreads
Event: 0.402 Executing VM operation: HandshakeAllThreads done
Events (20 events):
Event: 0.402 loading class java/lang/ProcessEnvironment$CheckedEntrySet$1
Event: 0.402 loading class java/lang/ProcessEnvironment$CheckedEntrySet$1 done
Event: 0.402 loading class java/lang/ProcessEnvironment$CheckedEntry
Event: 0.402 loading class java/lang/ProcessEnvironment$CheckedEntry done
Event: 0.412 loading class java/util/concurrent/CopyOnWriteArraySet
Event: 0.412 loading class java/util/concurrent/CopyOnWriteArraySet done
Event: 0.415 loading class java/util/concurrent/ConcurrentLinkedDeque
Event: 0.415 loading class java/util/concurrent/ConcurrentLinkedDeque done
Event: 0.415 loading class java/util/concurrent/ConcurrentLinkedDeque$Node
Event: 0.416 loading class java/util/concurrent/ConcurrentLinkedDeque$Node done
Event: 0.421 loading class sun/reflect/generics/tree/BottomSignature
Event: 0.421 loading class sun/reflect/generics/tree/BottomSignature done
Event: 0.421 loading class sun/reflect/generics/tree/Wildcard
Event: 0.421 loading class sun/reflect/generics/tree/Wildcard done
Event: 0.421 loading class sun/reflect/generics/reflectiveObjects/WildcardTypeImpl
Event: 0.421 loading class sun/reflect/generics/reflectiveObjects/WildcardTypeImpl done
Event: 0.424 loading class java/util/Currency
Event: 0.424 loading class java/util/Currency done
Event: 0.426 loading class java/util/UUID
Event: 0.426 loading class java/util/UUID done
Dynamic libraries:
0x00007ff7fdf40000 - 0x00007ff7fdf50000 C:\Program Files\Java\jdk-17.0.2\bin\java.exe
0x00007ff971070000 - 0x00007ff971268000 C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ff96f110000 - 0x00007ff96f1cf000 C:\WINDOWS\System32\KERNEL32.DLL
0x00007ff96eb70000 - 0x00007ff96ee42000 C:\WINDOWS\System32\KERNELBASE.dll
0x00007ff96e760000 - 0x00007ff96e860000 C:\WINDOWS\System32\ucrtbase.dll
0x00007ff957c40000 - 0x00007ff957c5a000 C:\Program Files\Java\jdk-17.0.2\bin\VCRUNTIME140.dll
0x00007ff950ea0000 - 0x00007ff950eb8000 C:\Program Files\Java\jdk-17.0.2\bin\jli.dll
0x00007ff96fa40000 - 0x00007ff96faee000 C:\WINDOWS\System32\ADVAPI32.dll
0x00007ff96fb30000 - 0x00007ff96fbce000 C:\WINDOWS\System32\msvcrt.dll
0x00007ff970f90000 - 0x00007ff97102c000 C:\WINDOWS\System32\sechost.dll
0x00007ff96fbd0000 - 0x00007ff96fcf5000 C:\WINDOWS\System32\RPCRT4.dll
0x00007ff96f7e0000 - 0x00007ff96f981000 C:\WINDOWS\System32\USER32.dll
0x00007ff96f080000 - 0x00007ff96f0a2000 C:\WINDOWS\System32\win32u.dll
0x00007ff96f1d0000 - 0x00007ff96f1fb000 C:\WINDOWS\System32\GDI32.dll
0x00007ff96e8f0000 - 0x00007ff96e9ff000 C:\WINDOWS\System32\gdi32full.dll
0x00007ff96ee50000 - 0x00007ff96eeed000 C:\WINDOWS\System32\msvcp_win.dll
0x00007ff93f090000 - 0x00007ff93f32a000 C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_60b5254171f9507e\COMCTL32.dll
0x00007ff965030000 - 0x00007ff96503a000 C:\WINDOWS\SYSTEM32\VERSION.dll
0x00007ff96faf0000 - 0x00007ff96fb22000 C:\WINDOWS\System32\IMM32.DLL
0x00007ff968b30000 - 0x00007ff968b3c000 C:\Program Files\Java\jdk-17.0.2\bin\vcruntime140_1.dll
0x00007ff926df0000 - 0x00007ff926e7d000 C:\Program Files\Java\jdk-17.0.2\bin\msvcp140.dll
0x00007ff8fce60000 - 0x00007ff8fda21000 C:\Program Files\Java\jdk-17.0.2\bin\server\jvm.dll
0x00007ff96ffc0000 - 0x00007ff96ffc8000 C:\WINDOWS\System32\PSAPI.DLL
0x00007ff954050000 - 0x00007ff954059000 C:\WINDOWS\SYSTEM32\WSOCK32.dll
0x00007ff957ae0000 - 0x00007ff957b07000 C:\WINDOWS\SYSTEM32\WINMM.dll
0x00007ff96ffd0000 - 0x00007ff97003b000 C:\WINDOWS\System32\WS2_32.dll
0x00007ff96cfc0000 - 0x00007ff96cfd2000 C:\WINDOWS\SYSTEM32\kernel.appcore.dll
0x00007ff95c4a0000 - 0x00007ff95c4aa000 C:\Program Files\Java\jdk-17.0.2\bin\jimage.dll
0x00007ff96c4e0000 - 0x00007ff96c6c4000 C:\WINDOWS\SYSTEM32\DBGHELP.DLL
0x00007ff95bc50000 - 0x00007ff95bc85000 C:\WINDOWS\SYSTEM32\dbgcore.DLL
0x00007ff96e860000 - 0x00007ff96e8e2000 C:\WINDOWS\System32\bcryptPrimitives.dll
0x00007ff936340000 - 0x00007ff936365000 C:\Program Files\Java\jdk-17.0.2\bin\java.dll
0x00007ff90f000000 - 0x00007ff90f0d6000 C:\Program Files\Java\jdk-17.0.2\bin\jsvml.dll
0x00007ff970040000 - 0x00007ff970784000 C:\WINDOWS\System32\SHELL32.dll
0x00007ff96c7c0000 - 0x00007ff96cf52000 C:\WINDOWS\SYSTEM32\windows.storage.dll
0x00007ff96f480000 - 0x00007ff96f7d5000 C:\WINDOWS\System32\combase.dll
0x00007ff96e150000 - 0x00007ff96e180000 C:\WINDOWS\SYSTEM32\Wldp.dll
0x00007ff96f990000 - 0x00007ff96fa3d000 C:\WINDOWS\System32\SHCORE.dll
0x00007ff96f200000 - 0x00007ff96f255000 C:\WINDOWS\System32\shlwapi.dll
0x00007ff96e6a0000 - 0x00007ff96e6bf000 C:\WINDOWS\SYSTEM32\profapi.dll
0x00007ff950a50000 - 0x00007ff950a69000 C:\Program Files\Java\jdk-17.0.2\bin\net.dll
0x00007ff962870000 - 0x00007ff96297c000 C:\WINDOWS\SYSTEM32\WINHTTP.dll
0x00007ff96de40000 - 0x00007ff96deaa000 C:\WINDOWS\system32\mswsock.dll
0x00007ff935fb0000 - 0x00007ff935fc6000 C:\Program Files\Java\jdk-17.0.2\bin\nio.dll
0x00007ff934cf0000 - 0x00007ff934d08000 C:\Program Files\Java\jdk-17.0.2\bin\zip.dll
0x00007ff953be0000 - 0x00007ff953bf0000 C:\Program Files\Java\jdk-17.0.2\bin\verify.dll
dbghelp: loaded successfully - version: 4.0.5 - missing functions: none
symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;C:\Program Files\Java\jdk-17.0.2\bin;C:\WINDOWS\SYSTEM32;C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_60b5254171f9507e;C:\Program Files\Java\jdk-17.0.2\bin\server
VM Arguments:
jvm_args: -XX:TieredStopAtLevel=1 -Dfile.encoding=windows-1251 -Duser.country=RU -Duser.language=ru -Duser.variant
java_command: ru.ip.labs.labs.LabsApplication
java_class_path (initial): C:\Users\àäìèí\IdeaProjects\PIbd-22_Karamushko_M_K_IP_Labs\build\classes\java\main;C:\Users\àäìèí\IdeaProjects\PIbd-22_Karamushko_M_K_IP_Labs\build\resources\main;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework\spring-webmvc\5.3.25\62a8258bcc4f7a58dd69af5140481b64653c90\spring-webmvc-5.3.25.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework\spring-web\5.3.25\c69815e7931cd3ce7f19cc8028fd1c36626120d6\spring-web-5.3.25.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-autoconfigure\2.7.8\cb835d82d00116e907d341d11096c3476ab49721\spring-boot-autoconfigure-2.7.8.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot\2.7.8\8db5af0f1171bb402c27a85fe97d741bddaa6fee\spring-boot-2.7.8.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\jakarta.annotation\jakarta.annotation-api\1.3.5\59eb84ee0d616332ff44aba065f3888cf002cd2d\jakarta.annotation-api-1.3.5.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework\spring-context\5.3.25\268a70ce4f44333ce0f13304c5f8c53b3df5f5f4\spring-context-5.3.25.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework\spring-expression\5.3.25\d681cdb86611f03d8ef29654edde219fe5afef1d\spring-expression-5.3.25.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aop\5.3.25\722e30759b29331726f9deed76f80b22345ee627\spring-aop-5.3.25.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework\spring-beans\5.3.25\b3aeae036b4ea1abfa1f9604d452e19664efe5f6\spring-beans-5.3.25.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.springframework\spring-core\5.3.25\85382e86321227506bf7f97ed80e2ab88bce25f0\spring-core-5.3.25.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.30\8fde7fe2586328ac3c68db92045e1c8759125000\snakeyaml-1.30.jar;C:\Users\àäìèí\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.d
Launcher Type: SUN_STANDARD
[Global flags]
intx CICompilerCount = 3 {product} {ergonomic}
uint ConcGCThreads = 1 {product} {ergonomic}
uint G1ConcRefinementThreads = 4 {product} {ergonomic}
size_t G1HeapRegionSize = 2097152 {product} {ergonomic}
uintx GCDrainStackTargetSize = 64 {product} {ergonomic}
size_t InitialHeapSize = 266338304 {product} {ergonomic}
size_t MarkStackSize = 4194304 {product} {ergonomic}
size_t MaxHeapSize = 4248829952 {product} {ergonomic}
size_t MaxNewSize = 2548039680 {product} {ergonomic}
size_t MinHeapDeltaBytes = 2097152 {product} {ergonomic}
size_t MinHeapSize = 8388608 {product} {ergonomic}
uintx NonProfiledCodeHeapSize = 0 {pd product} {ergonomic}
bool ProfileInterpreter = false {pd product} {command line}
uintx ProfiledCodeHeapSize = 0 {pd product} {ergonomic}
size_t SoftMaxHeapSize = 4248829952 {manageable} {ergonomic}
intx TieredStopAtLevel = 1 {product} {command line}
bool UseCompressedClassPointers = true {product lp64_product} {ergonomic}
bool UseCompressedOops = true {product lp64_product} {ergonomic}
bool UseG1GC = true {product} {ergonomic}
bool UseLargePagesIndividualAllocation = false {pd product} {ergonomic}
Logging:
Log output configuration:
#0: stdout all=warning uptime,level,tags
#1: stderr all=off uptime,level,tags
Environment Variables:
JAVA_HOME=C:\Program Files\Java\jdk-17.0.2
PATH=C:\Program Files\Common Files\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\windows\System32\OpenSSH\;C:\Program Files\Git\cmd;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\Yarn\bin\;C:\emacs\bin\;C:\Users\àäìèí\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\àäìèí\.dotnet\tools;C:\Users\àäìèí\AppData\Local\Yarn\bin;C:\Users\àäìèí\AppData\Roaming\npm;C:\Program Files\Java\jdk-11\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\apache-maven-3.8.5\bin;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\dotnet\;C:\Program Files\nodejs\;C:\Users\àäìèí\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\àäìèí\.dotnet\tools;C:\Users\àäìèí\AppData\Local\Yarn\bin;C:\Program Files\Java\jdk-11\bin;C:\Users\àäìèí\AppData\Local\Microsoft\WindowsApps;C:\Users\àäìèí\AppData\Local\GitHubDesktop\bin;C:\Users\àäìèí\.dotnet\tools;C:\Users\àäìèí\AppData\Roaming\npm;C:\Users\àäìèí\AppData\Local\Programs\Python\Python310\Scripts;C:\Users\àäìèí\Desktop\work\Óíèâåð\ÝÂÌ\assembler\fasm\INCLUDE;
USERNAME=àäìèí
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 142 Stepping 12, GenuineIntel
--------------- S Y S T E M ---------------
OS:
Windows 10 , 64 bit Build 19041 (10.0.19041.2364)
OS uptime: 2 days 22:39 hours
Hyper-V role detected
CPU: total 4 (initial active 4) (2 cores per cpu, 2 threads per core) family 6 model 142 stepping 12 microcode 0xb8, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, adx, fma, vzeroupper, clflush, clflushopt, hv
Memory: 4k page, system-wide physical 16205M (3237M free)
TotalPageFile size 18221M (AvailPageFile size 5M)
current process WorkingSet (physical memory assigned to process): 57M, peak: 57M
current process commit charge ("private bytes"): 338M, peak: 338M
vm_info: Java HotSpot(TM) 64-Bit Server VM (17.0.2+8-LTS-86) for windows-amd64 JRE (17.0.2+8-LTS-86), built on Dec 7 2021 21:51:03 by "mach5one" with MS VC++ 16.8 / 16.9 (VS2019)
END.

View File

@ -2,47 +2,7 @@ package ru.ip.labs.labs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
@SpringBootApplication
@RestController
public class LabsApplication {
public static void main(String[] args) {
SpringApplication.run(LabsApplication.class, args);
}
int getDegree(int x, int y) {
if(y == 1) return x;
int res = getDegree(x, y / 2);
res *= res;
if(y % 2 != 0) res *= x;
return res;
}
@GetMapping("/sum")
public int sum(@RequestParam int x, @RequestParam int y) {
return x + y;
}
@GetMapping("/diff")
public int diff(@RequestParam int x, @RequestParam int y) {
return x - y;
}
@GetMapping("/multiply")
public double multiply(@RequestParam double x, @RequestParam double y) {
return x * y;
}
@GetMapping("/divide")
public double divide(@RequestParam double x, @RequestParam double y) {
return x / y;
}
@GetMapping("/degree")
public int degree(@RequestParam int x, @RequestParam int y) {
return getDegree(x, y);
}
}

View File

@ -2,12 +2,27 @@ package ru.ip.labs.labs;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
public static final String REST_API = "/api";
@Override
public void addViewControllers(ViewControllerRegistry registry) {
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("films");
registry.addViewController("contacts");
registry.addViewController("catalogs");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/css/**").addResourceLocations("/static/css/");
}
}

View File

@ -0,0 +1,82 @@
package ru.ip.labs.labs.calculator.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ru.ip.labs.labs.calculator.service.CalculatorService;
@RestController
@RequestMapping("/test")
public class CalcController {
private final CalculatorService calculatorService;
public CalcController(CalculatorService calculatorService) {
this.calculatorService = calculatorService;
}
@GetMapping("/hello")
public String hello() {
return "Hi man";
}
@GetMapping("/sumInt")
public int sumInt(@RequestParam int x, @RequestParam int y) {
return calculatorService.getSum(x, y, "int");
}
@GetMapping("/sumString")
public String sumString(@RequestParam String x, @RequestParam int y) {
return calculatorService.getSum(x, y, "string");
}
@GetMapping("/sumArray")
public String sumArray(@RequestParam String x, int y) {
return calculatorService.getSum(x, y, "array");
}
@GetMapping("/diffInt")
public int diffInt(@RequestParam int x, @RequestParam int y) {
return calculatorService.getDiff(x, y, "int");
}
@GetMapping("/diffString")
public String diffString(@RequestParam String x, @RequestParam int y) {
return calculatorService.getDiff(x, y, "string");
}
@GetMapping("/diffArray")
public String diffArray(@RequestParam String x, int y) {
return calculatorService.getDiff(x, y, "array");
}
@GetMapping("/multipleInt")
public int multipleInt(@RequestParam int x, @RequestParam int y) {
return calculatorService.getMultiple(x, y, "int");
}
@GetMapping("/multipleString")
public String multipleString(@RequestParam String x, @RequestParam int y) {
return calculatorService.getMultiple(x, y, "string");
}
@GetMapping("/multipleArray")
public String multipleArray(@RequestParam String x, int y) {
return calculatorService.getMultiple(x, y, "array");
}
@GetMapping("/divideInt")
public int divideInt(@RequestParam int x, @RequestParam int y) {
return calculatorService.getDivide(x, y, "int");
}
@GetMapping("/divideString")
public String divideString(@RequestParam String x, @RequestParam int y) {
return calculatorService.getDivide(x, y, "string");
}
@GetMapping("/divideArray")
public String divideArray(@RequestParam String x, int y) {
return calculatorService.getDivide(x, y, "array");
}
}

View File

@ -0,0 +1,8 @@
package ru.ip.labs.labs.calculator.domain;
public interface Calculator<T> {
public T sum(T x, int y);
public T diff(T x, int y);
public T multiple(T x, int y);
public T divide(T x, int y);
}

View File

@ -0,0 +1,66 @@
package ru.ip.labs.labs.calculator.domain;
import org.springframework.stereotype.Component;
@Component(value = "testDatabase")
public class CalculatorArray implements Calculator<String> {
@Override
public String sum(String x, int y) {
String arr[] = x.split(",");
for(int i = 0; i < arr.length; ++i) {
try {
Integer first = Integer.parseInt(arr[i]);
arr[i] = (first + y) + "";
} catch (Exception err) {
arr[i] = "NaN";
}
}
return String.join(",", arr);
}
@Override
public String diff(String x, int y) {
String arr[] = x.split(",");
for(int i = 0; i < arr.length; ++i) {
try {
Integer first = Integer.parseInt(arr[i]);
arr[i] = (first - y) + "";
} catch (Exception err) {
arr[i] = "NaN";
}
}
return String.join(",", arr);
}
@Override
public String multiple(String x, int y) {
String arr[] = x.split(",");
for(int i = 0; i < arr.length; ++i) {
try {
Integer first = Integer.parseInt(arr[i]);
arr[i] = (first * y) + "";
} catch (Exception err) {
arr[i] = "NaN";
}
}
return String.join(",", arr);
}
@Override
public String divide(String x, int y) {
String arr[] = x.split(",");
for(int i = 0; i < arr.length; ++i) {
try {
Integer first = Integer.parseInt(arr[i]);
arr[i] = (first / y) + "";
} catch (Exception err) {
arr[i] = "NaN";
}
}
return String.join(",", arr);
}
}

View File

@ -0,0 +1,26 @@
package ru.ip.labs.labs.calculator.domain;
import org.springframework.stereotype.Component;
@Component(value = "int")
public class IntCalculator implements Calculator<Integer> {
@Override
public Integer sum(Integer x, int y) {
return x + y;
}
@Override
public Integer diff(Integer x, int y) {
return x - y;
}
@Override
public Integer multiple(Integer x, int y) {
return x * y;
}
@Override
public Integer divide(Integer x, int y) {
return x / y;
}
}

View File

@ -0,0 +1,41 @@
package ru.ip.labs.labs.calculator.domain;
import org.springframework.stereotype.Component;
@Component(value = "string")
public class StringCalculator implements Calculator<String> {
@Override
public String sum(String x, int y) {
return x + (y + "");
}
@Override
public String diff(String x, int y) {
String res = "";
int ySize = (y + "").length();
for(int i = 0; i < x.length(); ++i) {
int index = x.indexOf(y + "", i - ySize);
if(index - i < ySize && i >= index) continue;
res += x.charAt(i);
}
return res;
}
@Override
public String multiple(String x, int y) {
String res = "";
for(int i = 0; i < y; ++i) res += x;
return res;
}
@Override
public String divide(String x, int y) {
int len = x.length() / y;
String res = "";
for(int i = 0; i < len; ++i) res += x.charAt(i);
return res;
}
}

View File

@ -0,0 +1,35 @@
package ru.ip.labs.labs.calculator.service;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import ru.ip.labs.labs.calculator.domain.Calculator;
@Service
public class CalculatorService {
private final ApplicationContext _applicationContext;
public CalculatorService(ApplicationContext applicationContext) {
this._applicationContext = applicationContext;
}
public <T> T getSum(T x, int y, String opType) {
Calculator<T> calc = (Calculator<T>)_applicationContext.getBean(opType);
return calc.sum(x, y);
}
public <T> T getDiff(T x, int y, String opType) {
Calculator<T> calc = (Calculator<T>)_applicationContext.getBean(opType);
return calc.diff(x, y);
}
public <T> T getMultiple(T x, int y, String opType) {
Calculator<T> calc = (Calculator<T>)_applicationContext.getBean(opType);
return calc.multiple(x, y);
}
public <T> T getDivide(T x, int y, String opType) {
Calculator<T> calc = (Calculator<T>)_applicationContext.getBean(opType);
return calc.divide(x, y);
}
}

View File

@ -0,0 +1,44 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.WebConfiguration;
import ru.ip.labs.labs.films.dto.ActorDTO;
import ru.ip.labs.labs.films.service.ActorService;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping(WebConfiguration.REST_API + "/actors")
public class ActorController {
private final ActorService actorService;
public ActorController(ActorService actorService) {
this.actorService = actorService;
}
@GetMapping("/{id}")
public ActorDTO getActor(@PathVariable Long id) {
return new ActorDTO(actorService.findActor(id));
}
@GetMapping("")
public List<ActorDTO> getActors() {
return actorService.findAllActors().stream().map(ActorDTO::new).toList();
}
@PostMapping("")
public ActorDTO createActor(@RequestBody @Valid ActorDTO actor) {
return new ActorDTO(actorService.addActor(actor.getName(), actor.getSurname()));
}
@PatchMapping("/{id}")
public ActorDTO updateActor(@PathVariable Long id, @RequestBody @Valid ActorDTO actor) {
return new ActorDTO(actorService.updateActor(id, actor.getName(), actor.getSurname()));
}
@DeleteMapping("/{id}")
public ActorDTO deleteActor(@PathVariable Long id) {
return new ActorDTO(actorService.deleteActor(id));
}
}

View File

@ -0,0 +1,52 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.films.dto.ActorDTO;
import ru.ip.labs.labs.films.service.ActorService;
import javax.validation.Valid;
@Controller
@RequestMapping("/actor")
public class ActorMvcController {
private ActorService actorService;
public ActorMvcController(ActorService actorService) {
this.actorService = actorService;
}
@GetMapping
public String getActors(Model model) {
model.addAttribute("actors",
actorService.findAllActors().stream()
.map(ActorDTO::new).toList());
model.addAttribute("actorDTO", new ActorDTO());
return "actors-catalog";
}
@PostMapping(value = {"", "/{id}"})
public String saveActor(@PathVariable(required = false) Long id,
@ModelAttribute @Valid ActorDTO actorDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "actors-catalog";
}
if (id == null || id <= 0) {
actorService.addActor(actorDTO.getName(), actorDTO.getSurname());
} else {
actorService.updateActor(id, actorDTO.getName(), actorDTO.getSurname());
}
return "redirect:/actor";
}
@PostMapping("/delete/{id}")
public String deleteGenre(@PathVariable Long id) {
actorService.deleteActor(id);
return "redirect:/actor";
}
}

View File

@ -0,0 +1,58 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.WebConfiguration;
import ru.ip.labs.labs.films.dto.FilmDTO;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.models.Genre;
import ru.ip.labs.labs.films.service.FilmsService;
import javax.validation.Valid;
import java.util.Iterator;
import java.util.List;
@RestController
@RequestMapping(WebConfiguration.REST_API + "/films")
public class FilmController {
private final FilmsService filmService;
public FilmController(FilmsService filmService) {
this.filmService = filmService;
}
@GetMapping("/{id}")
public FilmDTO getFilm(@PathVariable Long id) {
return new FilmDTO(filmService.findFilm(id));
}
@GetMapping("")
public List<FilmDTO> getFilms() {
return filmService.findAllFilms().stream().map(FilmDTO::new).toList();
}
@PostMapping("")
public FilmDTO createFilm(@RequestBody @Valid FilmDTO film) {
return new FilmDTO(filmService.addFilm(film.getName(), film.getGenre(), film.getFullNames()));
}
@PatchMapping("/{id}")
public FilmDTO updateFilm(@PathVariable Long id,
@RequestBody @Valid FilmDTO film) {
return new FilmDTO(filmService.updateFilm(id, film.getName(), film.getGenre(), film.getFullNames()));
}
@PatchMapping("/add_genre/{id}")
public FilmDTO addGenre(@PathVariable Long id, @RequestParam Long genre_id) {
return new FilmDTO(filmService.addGenre(id, genre_id));
}
@PatchMapping("/add_actor/{id}")
public FilmDTO addActor(@PathVariable Long id, @RequestParam Long actor_id) {
return new FilmDTO(filmService.addActor(id, actor_id));
}
@DeleteMapping("/{id}")
public FilmDTO deleteFilm(@PathVariable Long id) {
return new FilmDTO(filmService.deleteFilm(id));
}
}

View File

@ -0,0 +1,66 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.films.dto.FilmDTO;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.service.ActorService;
import ru.ip.labs.labs.films.service.FilmsService;
import ru.ip.labs.labs.films.service.GenreService;
import javax.validation.Valid;
@Controller
@RequestMapping("/film")
public class FilmMvcController {
private FilmsService filmService;
private GenreService genreService;
private ActorService actorService;
public FilmMvcController(FilmsService filmService, GenreService genreService, ActorService actorService) {
this.filmService = filmService;
this.genreService = genreService;
this.actorService = actorService;
}
@GetMapping
public String getFilms(Model model) {
model.addAttribute("films",
filmService.findAllFilms().stream()
.map(FilmDTO::new).toList());
model.addAttribute("filmDTO", new FilmDTO());
model.addAttribute("allGenres",
genreService.findAllGenres().stream()
.map(g -> g.getName()).toList());
model.addAttribute("allActors",
actorService.findAllActors().stream()
.map(a -> a.getName() + " " + a.getSurname()).toList());
return "films-catalog";
}
@PostMapping(value = {"", "/{id}"})
public String saveFilm(@PathVariable(required = false) Long id,
@ModelAttribute @Valid FilmDTO filmDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "films-catalog";
}
if (id == null || id <= 0) {
filmService.addFilm(filmDTO.getName(), filmDTO.getGenre(), filmDTO.getFullNames());
} else {
filmService.updateFilm(id, filmDTO.getName(), filmDTO.getGenre(), filmDTO.getFullNames());
}
return "redirect:/film";
}
@PostMapping("/delete/{id}")
public String deleteGenre(@PathVariable Long id) {
filmService.deleteFilm(id);
return "redirect:/film";
}
}

View File

@ -0,0 +1,50 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.WebConfiguration;
import ru.ip.labs.labs.films.dto.FilmDTO;
import ru.ip.labs.labs.films.dto.GenreDTO;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.models.Genre;
import ru.ip.labs.labs.films.service.FilmsService;
import ru.ip.labs.labs.films.service.GenreService;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping(WebConfiguration.REST_API + "/genres")
public class GenreController {
private final GenreService genreService;
public GenreController(GenreService genreService) {
this.genreService = genreService;
}
@GetMapping("/{id}")
public GenreDTO getGenre(@PathVariable Long id) {
return new GenreDTO(genreService.findGenre(id));
}
@GetMapping("")
public List<GenreDTO> getGenres() {
return genreService.findAllGenres().stream().map(GenreDTO::new).toList();
}
@PostMapping("")
public GenreDTO createGenre(@RequestBody @Valid GenreDTO genre) {
return new GenreDTO(genreService.addGenre(genre.getName()));
}
@PatchMapping("/{id}")
public GenreDTO updateGenre(@PathVariable Long id,
@RequestBody @Valid GenreDTO genre) {
return new GenreDTO(genreService.updateGenre(id, genre.getName()));
}
@DeleteMapping("/{id}")
public GenreDTO deleteGenre(@PathVariable Long id) {
return new GenreDTO(genreService.deleteGenre(id));
}
}

View File

@ -0,0 +1,52 @@
package ru.ip.labs.labs.films.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ip.labs.labs.films.dto.GenreDTO;
import ru.ip.labs.labs.films.service.GenreService;
import javax.validation.Valid;
@Controller
@RequestMapping("/genre")
public class GenreMvcController {
private GenreService genreService;
public GenreMvcController(GenreService genreService) {
this.genreService = genreService;
}
@GetMapping
public String getGenres(Model model) {
model.addAttribute("genres",
genreService.findAllGenres().stream()
.map(GenreDTO::new).toList());
model.addAttribute("genreDTO", new GenreDTO());
return "genres-catalog";
}
@PostMapping(value = {"", "/{id}"})
public String saveGenre(@PathVariable(required = false) Long id,
@ModelAttribute @Valid GenreDTO genreDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "genres-catalog";
}
if (id == null || id <= 0) {
genreService.addGenre(genreDTO.getName());
} else {
genreService.updateGenre(id, genreDTO.getName());
}
return "redirect:/genre";
}
@PostMapping("/delete/{id}")
public String deleteGenre(@PathVariable Long id) {
genreService.deleteGenre(id);
return "redirect:/genre";
}
}

View File

@ -0,0 +1,71 @@
package ru.ip.labs.labs.films.dto;
import ru.ip.labs.labs.films.models.Actor;
import ru.ip.labs.labs.films.models.Film;
import javax.persistence.FetchType;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
public class ActorDTO {
private Long id;
private String name;
private String surname;
private String fullName;
private List<Film> films;
public ActorDTO() {}
public ActorDTO(Actor actor) {
this.id = actor.getId();
this.name = actor.getName();
this.surname = actor.getSurname();
this.fullName = this.name + this.surname;
}
public ActorDTO(Long id, String name, String surname, byte[] photo) {
this.id = id;
this.name = name;
this.surname = surname;
this.fullName = this.name + this.surname;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void setName(String name) {
this.name = name;
}
public List<Film> getFilms() {
return films;
}
@Override
public String toString() {
String res = "\nFilm{" +
"id: " + id + "," +
"name: " + name + "," +
"surname: " + name + "," +
"films:" + (films == null ? "[]" : films.toString()) + "}"
;
return res;
}
}

View File

@ -0,0 +1,76 @@
package ru.ip.labs.labs.films.dto;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import ru.ip.labs.labs.films.models.Actor;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.models.Genre;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import java.util.List;
public class FilmDTO {
private Long id;
private String name;
private List<String> genre;
private List<String> fullNames;
public FilmDTO() {}
public FilmDTO(Film film) {
this.id = film.getId();
this.name = film.getName();
if(film.getGenres() != null) {
this.genre = film.getGenres().stream().map(Genre::getName).toList();
}
if(film.getActors() != null) {
this.fullNames = film.getActors().stream().map(actor -> actor.getName() + " " + actor.getSurname()).toList();
}
}
public FilmDTO(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getFullNames() {
return fullNames;
}
public void setFullNames(List<String> fullNames) {
this.fullNames = fullNames;
}
public List<String> getGenre() {
return genre;
}
public void setGenre(List<String> genre) {
this.genre = genre;
}
@Override
public String toString() {
String res = "\nFilm{" +
"id: " + id + "," +
"name: " + name + "," +
"genres:" + (genre == null ? "[]" : genre.toString()) + "}";
return res;
}
}

View File

@ -0,0 +1,39 @@
package ru.ip.labs.labs.films.dto;
import ru.ip.labs.labs.films.models.Genre;
public class GenreDTO {
private Long id;
private String name;
public GenreDTO() {}
public GenreDTO(Genre genre) {
this.id = genre.getId();
this.name = genre.getName();
}
public GenreDTO(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Genre{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

View File

@ -0,0 +1,74 @@
package ru.ip.labs.labs.films.models;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
@Entity
public class Actor {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String surname;
@Lob
private byte[] photo;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "actors")
private List<Film> films;
public Actor() {}
public Actor(String name, String surname) {
this.name = name;
this.surname = surname;
}
public byte[] getPhoto() {
return photo;
}
public void setPhoto(String path) throws IOException {
File f = new File(path);
photo = Files.readAllBytes(f.toPath());
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void setName(String name) {
this.name = name;
}
public List<Film> getFilms() {
return films;
}
@Override
public String toString() {
String res = "\nFilm{" +
"id: " + id + "," +
"name: " + name + "," +
"surname: " + name + "," +
"films:" + (films == null ? "[]" : films.toString()) + "}"
;
return res;
}
}

View File

@ -0,0 +1,96 @@
package ru.ip.labs.labs.films.models;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Entity
public class Film {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToMany
@LazyCollection(LazyCollectionOption.FALSE)
@JoinTable(name="films_genres",
joinColumns = @JoinColumn(name="film_id"),
inverseJoinColumns = @JoinColumn(name="genre_id")
)
private List<Genre> genres;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name="actors_films",
joinColumns = @JoinColumn(name="film_id"),
inverseJoinColumns = @JoinColumn(name="actor_id")
)
private List<Actor> actors;
public Film() {}
public Film(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addGenre(Genre g) {
if(genres == null) genres = new ArrayList<>();
genres.add(g);
}
public void deleteGenres() {
genres = null;
}
public void deleteActors() {
actors = null;
}
public void addActor(Actor actor) {
if(actors == null) actors = new ArrayList<>();
actors.add(actor);
}
public List<Actor> getActors() {
return actors;
}
public List<Genre> getGenres() {
return genres;
}
@Override
public String toString() {
String res = "\nFilm{" +
"id: " + id + "," +
"name: " + name + "," +
"genres:" + (genres == null ? "[]" : genres.toString()) + "}"
;
/*
Iterator<Genre> iter = genres.iterator();
while(iter.hasNext()) {
Genre curr = iter.next();
res += "{ id: " + curr.getId() + ", name: " + curr.getName() + (iter.hasNext() ? "}, " : "}");
}
res += "]\n}";*/
return res;
}
}

View File

@ -0,0 +1,36 @@
package ru.ip.labs.labs.films.models;
import javax.persistence.*;
import java.util.List;
@Entity
public class Genre {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public Genre() {}
public Genre(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Genre{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

View File

@ -0,0 +1,8 @@
package ru.ip.labs.labs.films.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ip.labs.labs.films.models.Actor;
public interface ActorRepository extends JpaRepository<Actor, Long> {
Actor findActorByNameAndSurname(String name, String surname);
}

View File

@ -0,0 +1,7 @@
package ru.ip.labs.labs.films.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ip.labs.labs.films.models.Film;
public interface FilmRepository extends JpaRepository<Film, Long> {
}

View File

@ -0,0 +1,8 @@
package ru.ip.labs.labs.films.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ip.labs.labs.films.models.Genre;
public interface GenreRepository extends JpaRepository<Genre, Long> {
Genre findByName(String name);
}

View File

@ -0,0 +1,113 @@
package ru.ip.labs.labs.films.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ip.labs.labs.films.models.Actor;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.repository.ActorRepository;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
@Service
public class ActorService {
private ActorRepository repo;
public ActorService(ActorRepository repo) {
this.repo = repo;
}
@Transactional
public Actor addActor(String name, String surname) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Student name is null or empty");
}
Actor actor = new Actor(name, surname);
return repo.save(actor);
}
@Transactional
public Actor addActor(String name, String surname, String path) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Student name is null or empty");
}
Actor actor = new Actor(name, surname);
try {
actor.setPhoto(path);
} catch(IOException err) {
// System.out.println(err.getMessage());
throw new RuntimeException(err);
}
return repo.save(actor);
}
@Transactional(readOnly = true)
public Actor findActor(Long id) {
final Optional<Actor> actor = repo.findById(id);
if (actor.isEmpty()) {
throw new EntityNotFoundException(String.format("Actor with id [%s] is not found", id));
}
return actor.get();
}
@Transactional(readOnly = true)
public Actor findByFullName(String name, String surname) {
if(!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Actor name is null or empty");
}
if(!StringUtils.hasText(surname)) {
throw new IllegalArgumentException("Actor surname is null or empty");
}
return repo.findActorByNameAndSurname(name, surname);
}
@Transactional(readOnly = true)
public List<Actor> findAllActors() {
return repo.findAll();
}
@Transactional
public Actor updateActor(Long id, String name, String surname) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Actor name is null or empty");
}
final Optional<Actor> currentActorOpt = repo.findById(id);
if(currentActorOpt.isEmpty()) {
return null;
}
final Actor currentActor = currentActorOpt.get();
if(name != null) currentActor.setName(name);
if(surname != null) currentActor.setSurname(surname);
return repo.save(currentActor);
}
@Transactional
public Actor deleteActor(Long id) {
final Optional<Actor> currentActor = repo.findById(id);
if(currentActor.isEmpty()) {
return null;
}
repo.deleteById(id);
return currentActor.get();
}
@Transactional
public void deleteAllActors() {
repo.deleteAll();
}
}

View File

@ -0,0 +1,200 @@
package ru.ip.labs.labs.films.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ip.labs.labs.films.models.Actor;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.models.Genre;
import ru.ip.labs.labs.films.repository.ActorRepository;
import ru.ip.labs.labs.films.repository.FilmRepository;
import ru.ip.labs.labs.films.repository.GenreRepository;
import javax.persistence.EntityNotFoundException;
import java.util.List;
import java.util.Optional;
@Service
public class FilmsService {
private FilmRepository repo;
private GenreService genreService;
private ActorService actorService;
public FilmsService(FilmRepository repo, ActorService actorService, GenreService genreService) {
this.repo = repo;
this.actorService = actorService;
this.genreService = genreService;
}
@Transactional
public Film addFilm(String name) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Student name is null or empty");
}
Film film = new Film(name);
return repo.save(film);
}
@Transactional
public Film addFilm(String name, List<String> genres, List<String> fullNames) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Student name is null or empty");
}
Film film = new Film(name);
Film result = repo.save(film);
updateGenres(result.getId(), genres);
return updateActors(film.getId(), fullNames);
}
// фильмы по жанру
// фильмы по актеру
@Transactional
public Film addGenre(Long filmId, Long genreId) {
final Optional<Film> filmOpt = repo.findById(filmId);
if (filmOpt.isEmpty()) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId));
}
Film film = filmOpt.get();
final Genre genre = genreService.findGenre(genreId);
if (genre == null) {
throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", genreId));
}
film.addGenre(genre);
return repo.save(film);
}
@Transactional
public Film updateGenres(Long filmId, List<String> genres) {
final Optional<Film> filmOpt = repo.findById(filmId);
if (filmOpt.isEmpty()) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId));
}
Film film = filmOpt.get();
film.deleteGenres();
for(String g : genres) {
Genre genre = genreService.findByName(g);
film.addGenre(genre);
}
return repo.save(film);
}
@Transactional
public Film updateActors(Long filmId, List<String> fullNames) {
final Optional<Film> filmOpt = repo.findById(filmId);
if (filmOpt.isEmpty()) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId));
}
Film film = filmOpt.get();
film.deleteActors();
for(String fn : fullNames) {
String arr[] = fn.split(" ");
Actor actor = actorService.findByFullName(arr[0], arr[1]);
film.addActor(actor);
}
return repo.save(film);
}
@Transactional
public Film addActor(Long filmId, Long actorId) {
final Optional<Film> filmOpt = repo.findById(filmId);
if (filmOpt.isEmpty()) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId));
}
Film film = filmOpt.get();
final Actor actor = actorService.findActor(actorId);
if (actor == null) {
throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", actorId));
}
film.addActor(actor);
return repo.save(film);
}
@Transactional(readOnly = true)
public Film findFilm(Long id) {
final Optional<Film> film = repo.findById(id);
if (film.isEmpty()) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", id));
}
return film.get();
}
@Transactional(readOnly = true)
public List<Film> findAllFilms() {
return repo.findAll();
}
@Transactional
public Film updateFilm(Long id, String name) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Film name is null or empty");
}
final Optional<Film> currentFilmOpt = repo.findById(id);
if(currentFilmOpt.isEmpty()) {
return null;
}
final Film currentFilm = currentFilmOpt.get();
currentFilm.setName(name);
return repo.save(currentFilm);
}
@Transactional
public Film updateFilm(Long id, String name, List<String> genres, List<String> fullNames) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Film name is null or empty");
}
final Optional<Film> currentFilmOpt = repo.findById(id);
if(currentFilmOpt.isEmpty()) {
return null;
}
final Film currentFilm = currentFilmOpt.get();
currentFilm.setName(name);
repo.save(currentFilm);
updateGenres(id, genres);
return updateActors(id, fullNames);
}
@Transactional
public Film deleteFilm(Long id) {
final Optional<Film> currentFilm = repo.findById(id);
if(currentFilm.isEmpty()) {
return null;
}
repo.deleteById(id);
return currentFilm.get();
}
@Transactional
public void deleteAllFilms() {
repo.deleteAll();
}
}

View File

@ -0,0 +1,85 @@
package ru.ip.labs.labs.films.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ip.labs.labs.films.models.Genre;
import ru.ip.labs.labs.films.repository.GenreRepository;
import javax.persistence.EntityNotFoundException;
import java.util.List;
import java.util.Optional;
@Service
public class GenreService {
private GenreRepository repo;
public GenreService(GenreRepository repo) {
this.repo = repo;
}
@Transactional
public Genre addGenre(String name) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Genre name is null or empty");
}
Genre genre = new Genre(name);
return repo.save(genre);
}
@Transactional(readOnly = true)
public Genre findGenre(Long id) {
final Optional<Genre> genre = repo.findById(id);
if (genre.isEmpty()) {
throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", id));
}
return genre.get();
}
@Transactional(readOnly = true)
public List<Genre> findAllGenres() {
return repo.findAll();
}
@Transactional
public Genre updateGenre(Long id, String name) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Film name is null or empty");
}
final Optional<Genre> currentGenreOpt = repo.findById(id);
if(currentGenreOpt.isEmpty()) {
return null;
}
final Genre currentGenre = currentGenreOpt.get();
currentGenre.setName(name);
return repo.save(currentGenre);
}
@Transactional
public Genre findByName(String name) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("Genre name is null or empty");
}
return repo.findByName(name);
}
@Transactional
public Genre deleteGenre(Long id) {
Optional<Genre> genre = repo.findById(id);
if(genre.isEmpty()) {
return null;
}
repo.deleteById(id);
return genre.get();
}
@Transactional
public void deleteAllGenres() {
repo.deleteAll();
}
}

View File

@ -1 +1,11 @@
spring.main.banner-mode=off
#server.port=8080
spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false

View File

@ -0,0 +1,23 @@
.banner-block {
width: 90%;
}
.banner-card {
width: 0;
height: 0;
overflow: hidden;
opacity: 0.2;
transition: 0.5s opacity ease;
}
.banner-card.active {
width: 100%;
height: auto;
opacity: 1;
margin: 0 auto;
}
.banner-card.active img {
height: 75vh;
}

View File

@ -0,0 +1,5 @@
.map__frame {
width: 90%;
height: 500px;
margin-bottom: 30px;
}

View File

@ -0,0 +1,21 @@
.navbar__logo {
text-decoration: none;
margin-left: 30px;
}
.navbar__logo-text {
font-size: 30px;
text-decoration: none;
color: white;
}
.navbar__logo-text_first {
color: yellow;
}
body {
margin: 0;
background: linear-gradient(135deg, #8bf292, #a5ebb1) fixed;
min-height: 100vh;
position: relative;
}

View File

@ -0,0 +1,3 @@
.selected {
background: #2150de;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="/css/Table.css">
</head>
<body>
<div layout:fragment="content">
<div class="m-3">
<div class="btn-group">
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-success" id="addBtn">Добавить</button>
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-info" id="editBtn">Изменить</button>
<button class="btn btn-danger" id="deleteBtn">Удалить</button>
</div>
<table class="table table-hover" id="table">
<thead>
<tr>
<th>#</th>
<th>Имя</th>
<th>Фамилия</th>
</tr>
</thead>
<tbody>
<tr th:each="actor, iterator: ${actors}" th:attr="onclick=|selectRow(${iterator.index})|" th:id="${actor.id}">
<!-- th:attr="onclick=|selectRow(1)"-->
<td th:text="${iterator.index} + 1"></td>
<td th:text="${actor.name}"></td>
<td th:text="${actor.surname}"></td>
</tr>
</tbody>
</table>
<div class="modal fade" tabIndex="-1" id="edit-modal"><!-- style={{ display: props.visible ? 'block' : 'none' }}-->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Добавление</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть" onClick={props.closeHandler}></button>
</div>
<form class="modal-body" method="post" id="edit-form">
<div class="mb-3">
<label htmlFor="genre" class="form-label">Имя</label>
<input type="text" th:field="${actorDTO.name}" name="name" class="form-control" required autoComplete="off">
</div>
<div class="mb-3">
<label htmlFor="genre" class="form-label">Фамилия</label>
<input type="text" th:field="${actorDTO.surname}" name="surname" class="form-control" required autoComplete="off">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="closeBtn" data-bs-dismiss="modal">Закрыть</button>
<button class="btn btn-primary" id="submitBtn" type="submit">Добавить</button>
</div>
</form>
</div>
</div>
</div>
</div>
<form method="post" style="display: none" id="delete-form">
</form>
</div>
<th:block layout:fragment="scripts">
<script>
let table = document.getElementById("table");
let addBtn = document.getElementById("addBtn");
let editBtn = document.getElementById("editBtn");
let deleteBtn = document.getElementById("deleteBtn");
let submitBtn = document.getElementById("submitBtn");
let closeBtn = document.getElementById("closeBtn");
let editForm = document.getElementById("edit-form");
let deleteForm = document.getElementById("delete-form");
let selectRow = (index) => {
table.children[1].children[index].classList.toggle("selected");
}
addBtn.onclick = () => {
editForm.action = "/actor";
editForm.previousElementSibling.children[0].textContent = "Добавление";
editForm.children[1].children[1].textContent = "Добавить";
editForm.name.value = "";
editForm.surname.value = "";
}
editBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
setTimeout(() => {
closeBtn.click();
}, 500);
return;
}
editForm.action = "/actor/" + elem.id;
editForm.previousElementSibling.children[0].textContent = "Изменение";
submitBtn.textContent = "Изменить";
editForm.name.value = elem.children[1].textContent;
editForm.surname.value = elem.children[2].textContent;
}
deleteBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
return;
}
deleteForm.action = "/actor/delete/" + elem.id;
deleteForm.submit();
}
</script>
</th:block>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<a href="/film" class="btn btn-success mt-1">фильмы</a>
<a href="/genre" class="btn btn-success mt-1">жанры</a>
<a href="/actor" class="btn btn-success mt-1">актеры</a>
</div>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
<link rel="stylesheet" href="/css/Contacts.css">
</head>
<body>
<div layout:fragment="content">
<h2 class="text-white">Контакты</h2>
<iframe class="map__frame" title="map" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d158855.07580070102!2d-0.2470504135400737!3d51.52953198005434!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47d8a00baf21de75%3A0x52963a5addd52a99!2z0JvQvtC90LTQvtC9LCDQktC10LvQuNC60L7QsdGA0LjRgtCw0L3QuNGP!5e0!3m2!1sru!2sru!4v1664443841067!5m2!1sru!2sru" loading="lazy"/>
</div>
</body>
</html>

View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="ru"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8"/>
<title>lumer</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="icon" href="/favicon.svg">
<link rel="stylesheet" href="/css/Header.css">
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
</head>
<body>
<nav class="navbar navbar-dark navbar-expand-lg bg-success">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<span class="navbar__logo-text navbar__logo-text_first">L</span><span class="navbar__logo-text navbar__logo-text_second">umer</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Переключатель навигации">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav" th:with="activeLink=${#request.requestURI}">
<li class="nav-item">
<a class="nav-link btn btn-success" aria-current="page" href="/"
th:classappend="${#strings.equals(activeLink, '/')} ? 'active' : ''">Главная</a>
</li>
<li class="nav-item">
<a class="nav-link btn btn-success" aria-current="page" href="/films"
th:classappend="${#strings.equals(activeLink, '/films')} ? 'active' : ''">Фильмы</a>
</li>
<li class="nav-item">
<a class="nav-link btn btn-success" aria-current="page" href="/contacts"
th:classappend="${#strings.equals(activeLink, '/contacts')} ? 'active' : ''">Контакты</a>
</li>
<li class="nav-item">
<a class="nav-link btn btn-success" aria-current="page" href="/catalogs"
th:classappend="${#strings.equals(activeLink, '/catalogs')} ? 'active' : ''">Каталог</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div layout:fragment="content">
</div>
</div>
</body>
<th:block layout:fragment="scripts">
</th:block>
</html>

View File

@ -0,0 +1,242 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="/css/Table.css">
</head>
<body>
<div layout:fragment="content">
<div class="m-3">
<div class="btn-group">
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-success" id="addBtn">Добавить</button>
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-info" id="editBtn">Изменить</button>
<button class="btn btn-danger" id="deleteBtn">Удалить</button>
</div>
<table class="table table-hover" id="table">
<thead>
<tr>
<th>#</th>
<th>Название</th>
<th>Жанры</th>
<th>Актеры</th>
</tr>
</thead>
<tbody>
<tr th:each="film, iterator: ${films}" th:attr="onclick=|selectRow(${iterator.index})|" th:id="${film.id}">
<!-- th:attr="onclick=|selectRow(1)"-->
<td th:text="${iterator.index} + 1"></td>
<td th:text="${film.name}"></td>
<td th:text="${#strings.arrayJoin(film.genre ,', ')}"></td>
<td th:text="${#strings.arrayJoin(film.fullNames ,', ')}"></td>
</tr>
</tbody>
</table>
<div class="modal fade" tabIndex="-1" id="edit-modal"><!-- style={{ display: props.visible ? 'block' : 'none' }}-->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Добавление</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть" onClick={props.closeHandler}></button>
</div>
<form class="modal-body" method="post" id="edit-form">
<div class="mb-3">
<label htmlFor="nameInput" class="form-label">Название</label>
<input id="nameInput" type="text" th:field="${filmDTO.name}" name="name" class="form-control" required autoComplete="off">
</div>
<select name="selectedGenre" class="form-select">
<option disabled value="">Укажите жанр</option>
<option th:each="g : ${allGenres}"
th:value="${g}"
th:text="${g}"></option>
</select>
<div id="selectedGenres">
</div>
<br>
<button type="button" class="btn btn-success" id="addGenre">Добавить жанр</button>
<select name="selectedActor" class="form-select">
<option disabled value="">Укажите актера</option>
<option th:each="a : ${allActors}"
th:value="${a}"
th:text="${a}"></option>
</select>
<div id="selectedActors">
</div>
<br>
<button type="button" class="btn btn-success" id="addActor">Добавить актера</button>
<select name="genre" class="form-select" th:field="${filmDTO.genre}" multiple="multiple" hidden>
<option th:each="g : ${allGenres}"
th:value="${g}"
th:text="${g}"></option>
</select>
<select name="fullNames" class="form-select" th:field="${filmDTO.fullNames}" multiple="multiple" hidden>
<option th:each="a : ${allActors}"
th:value="${a}"
th:text="${a}"></option>
</select>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="closeBtn" data-bs-dismiss="modal">Закрыть</button>
<button class="btn btn-primary" id="submitBtn" type="submit">Добавить</button>
</div>
</form>
</div>
</div>
</div>
</div>
<form method="post" style="display: none" id="delete-form">
</form>
</div>
<th:block layout:fragment="scripts">
<script>
let table = document.getElementById("table");
let addBtn = document.getElementById("addBtn");
let editBtn = document.getElementById("editBtn");
let submitBtn = document.getElementById("submitBtn");
let closeBtn = document.getElementById("closeBtn");
let addGenreBtn = document.getElementById("addGenre");
let addActorBtn = document.getElementById("addActor");
let editForm = document.getElementById("edit-form");
let deleteForm = document.getElementById("delete-form");
let selectRow = (index) => {
table.children[1].children[index].classList.toggle("selected");
}
addBtn.onclick = (e) => {
editForm.action = "/film";
editForm.previousElementSibling.children[0].textContent = "Добавление";
submitBtn.textContent = "Добавить";
editForm.name.value = "";
document.getElementById("selectedGenres").innerHTML = "";
for(let opt of editForm.genre.options) {
opt.selected = false;
}
document.getElementById("selectedActors").innerHTML = "";
for(let opt of editForm.fullNames.options) {
opt.selected = false;
}
}
editBtn.onclick = (e) => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
setTimeout(() => {
closeBtn.click();
}, 500);
return;
}
editForm.action = "/film/" + elem.id;
editForm.previousElementSibling.children[0].textContent = "Изменение";
submitBtn.textContent = "Изменить";
editForm.name.value = elem.children[1].textContent;
let genresArr = elem.children[2].textContent.split(", ");
document.getElementById("selectedGenres").innerHTML = "";
for(let opt of editForm.genre.options) {
if(genresArr.indexOf(opt.value) == -1) continue;
let budge = document.createElement("div");
budge.className = "badge bg-secondary m-1";
budge.innerHTML = `
<span>${opt.value}</span>
<button type="button" class="btn-close bg-danger m-1"></button>
`;
budge.children[1].onclick = () => {
budge.remove();
opt.selected = false;
}
document.getElementById("selectedGenres").appendChild(budge);
opt.selected = true;
}
let actorsArr = elem.children[3].textContent.split(", ");
document.getElementById("selectedActors").innerHTML = "";
for(let opt of editForm.fullNames.options) {
if(actorsArr.indexOf(opt.value) == -1) continue;
let budge = document.createElement("div");
budge.className = "badge bg-secondary m-1";
budge.innerHTML = `
<span>${opt.value}</span>
<button type="button" class="btn-close bg-danger m-1"></button>
`;
budge.children[1].onclick = () => {
budge.remove();
opt.selected = false;
}
document.getElementById("selectedActors").appendChild(budge);
opt.selected = true;
}
}
deleteBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
return;
}
deleteForm.action = "/film/delete/" + elem.id;
deleteForm.submit();
}
addGenreBtn.onclick = () => {
let selectedIndex = editForm.selectedGenre.selectedIndex;
let g = editForm.selectedGenre.options[selectedIndex].value;
for(let elem of editForm.genre.options) {
if(g != elem.value) continue;
if(elem.selected) return;
elem.selected = true;
let budge = document.createElement("div");
budge.className = "badge bg-secondary m-1";
budge.innerHTML = `
<span>${g}</span>
<button type="button" class="btn-close bg-danger m-1"></button>
`;
budge.children[1].onclick = () => {
budge.remove();
elem.selected = false;
}
document.getElementById("selectedGenres").appendChild(budge);
}
}
addActorBtn.onclick = () => {
let selectedIndex = editForm.selectedActor.selectedIndex;
let a = editForm.selectedActor.options[selectedIndex].value;
for(let elem of editForm.fullNames.options) {
if(a != elem.value) continue;
if(elem.selected) return;
elem.selected = true;
let budge = document.createElement("div");
budge.className = "badge bg-secondary m-1";
budge.innerHTML = `
<span>${a}</span>
<button type="button" class="btn-close bg-danger m-1"></button>
`;
budge.children[1].onclick = () => {
budge.remove();
elem.selected = false;
}
document.getElementById("selectedActors").appendChild(budge);
}
}
</script>
</th:block>
</body>
</html>

View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="/css/Banner.css">
</head>
<body>
<div layout:fragment="content">
<section class="categories">
<h2 class="text-white">Категории</h2>
<div class="btn-group">
<button class="btn btn-success">Комедии</button>
<button class="btn btn-success">Драмы</button>
<button class="btn btn-success">Трилер</button>
</div>
</section>
<section class="banner">
<h2 class="text-white">Все фильмы</h2>
<div class="banner-block" id="banner">
<div class="banner-card active">
<a href="/film">
<img src="/img/1.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/2.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/3.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/4.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/5.jpg"/>
</a>
</div>
</div>
</section>
</div>
<th:block layout:fragment="scripts">
<script>
let active = 0;
let banner = document.getElementById("banner")
setInterval(() => {
active += active == 4 ? -4 : 1;
document.querySelector(".banner-card.active").classList.remove("active");
banner.children[active].classList.add("active");
}, 3000);
</script>
</th:block>
</body>
</html>

View File

@ -0,0 +1,102 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" href="/css/Table.css">
</head>
<body>
<div layout:fragment="content">
<div class="m-3">
<div class="btn-group">
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-success" id="addBtn">Добавить</button>
<button data-bs-target="#edit-modal" data-bs-toggle="modal" class="btn btn-info" id="editBtn">Изменить</button>
<button class="btn btn-danger" id="deleteBtn">Удалить</button>
</div>
<table class="table table-hover" id="table">
<thead>
<tr>
<th>#</th>
<th>Жанр</th>
</tr>
</thead>
<tbody>
<tr th:each="genre, iterator: ${genres}" th:attr="onclick=|selectRow(${iterator.index})|" th:id="${genre.id}">
<!-- th:attr="onclick=|selectRow(1)"-->
<td th:text="${iterator.index} + 1"></td>
<td th:text="${genre.name}"></td>
</tr>
</tbody>
</table>
<div class="modal fade" tabIndex="-1" id="edit-modal"><!-- style={{ display: props.visible ? 'block' : 'none' }}-->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Добавление</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть" onClick={props.closeHandler}></button>
</div>
<form class="modal-body" method="post" id="edit-form">
<div class="mb-3">
<label htmlFor="genre" class="form-label">Название</label>
<input type="text" th:field="${genreDTO.name}" name="name" class="form-control" required autoComplete="off">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="closeBtn" data-bs-dismiss="modal">Закрыть</button>
<button class="btn btn-primary" id="submitBtn" type="submit">Добавить</button>
</div>
</form>
</div>
</div>
</div>
</div>
<form method="post" style="display: none" id="delete-form">
</form>
</div>
<th:block layout:fragment="scripts">
<script>
let table = document.getElementById("table");
let addBtn = document.getElementById("addBtn");
let editBtn = document.getElementById("editBtn");
let submitBtn = document.getElementById("submitBtn");
let closeBtn = document.getElementById("closeBtn");
let editForm = document.getElementById("edit-form");
let deleteForm = document.getElementById("delete-form");
let selectRow = (index) => {
table.children[1].children[index].classList.toggle("selected");
}
addBtn.onclick = (e) => {
editForm.action = "/genre";
editForm.previousElementSibling.children[0].textContent = "Добавление";
editForm.children[1].children[1].textContent = "Добавить";
editForm.name.value = "";
}
editBtn.onclick = (e) => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
setTimeout(() => {
closeBtn.click();
}, 500);
return;
}
editForm.action = "/genre/" + elem.id;
editForm.previousElementSibling.children[0].textContent = "Изменение";
submitBtn.textContent = "Изменить";
editForm.name.value = elem.children[1].textContent;
}
deleteBtn.onclick = () => {
let elem = document.querySelector(".selected");
if(elem == undefined) {
return;
}
deleteForm.action = "/genre/delete/" + elem.id;
deleteForm.submit();
}
</script>
</th:block>
</body>
</html>

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/html">
<head>
<link rel="stylesheet" href="/css/Banner.css">
</head>
<body>
<div layout:fragment="content">
<h2 class="text-white">Популярные</h2>
<div class="banner-block" id="banner">
<div class="banner-card active">
<a href="/film">
<img src="/img/1.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/2.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/3.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/4.jpg"/>
</a>
</div>
<div class="banner-card">
<a href="/film">
<img src="/img/5.jpg"/>
</a>
</div>
</div>
</div>
<th:block layout:fragment="scripts">
<script>
let active = 0;
let banner = document.getElementById("banner")
setInterval(() => {
active += active == 4 ? -4 : 1;
document.querySelector(".banner-card.active").classList.remove("active");
banner.children[active].classList.add("active");
}, 3000);
</script>
</th:block>
</body>
</html>

View File

@ -0,0 +1,106 @@
package ru.ip.labs.labs;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ip.labs.labs.films.models.Actor;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.models.Genre;
import ru.ip.labs.labs.films.service.ActorService;
import ru.ip.labs.labs.films.service.FilmsService;
import ru.ip.labs.labs.films.service.GenreService;
import javax.persistence.EntityNotFoundException;
import java.util.List;
@SpringBootTest
public class JpaActorsTest {
private static final Logger log = LoggerFactory.getLogger(JpaFilmsTest.class);
@Autowired
FilmsService filmService;
@Autowired
ActorService actorService;
@Test
void testActorCreate() {
filmService.deleteAllFilms();
actorService.deleteAllActors();
final Actor actor = actorService.addActor("Victor", "Ivanov");
log.info(actor.toString());
Assertions.assertNotNull(actor.getId());
}
@Test
void testActorReadNotFound() {
actorService.deleteAllActors();
Assertions.assertThrows(EntityNotFoundException.class, () -> actorService.findActor(-1L));
}
@Test
void findActor() {
filmService.deleteAllFilms();
actorService.deleteAllActors();
final Actor actor = actorService.addActor("Victor", "Ivanov");
log.info(actor.toString());
final Actor findActor = actorService.findActor(actor.getId());
log.info(findActor.toString());
Assertions.assertEquals(actor.toString(), findActor.toString());
}
@Test
void testReadAll() {
filmService.deleteAllFilms();
actorService.deleteAllActors();
final Actor actor = actorService.addActor("Victor", "Ivanov");
log.info(actor.toString());
final List<Actor> actors = actorService.findAllActors();
Assertions.assertEquals(actors.size(), 1);
}
@Test
void updateActor() {
filmService.deleteAllFilms();
actorService.deleteAllActors();
final Actor actor = actorService.addActor("Victor", "Ivanov");
actorService.updateActor(actor.getId(), "Terminator", null);
final Actor findActor = actorService.findActor(actor.getId());
log.info(findActor.toString());
Assertions.assertEquals(findActor.getName() + " " + findActor.getSurname(), "Terminator Ivanov");
}
@Test
void deleteActor() {
filmService.deleteAllFilms();
actorService.deleteAllActors();
final Actor actor = actorService.addActor("Victor", "Ivanov");
log.info(actor.toString());
actorService.deleteActor(actor.getId());
Assertions.assertThrows(EntityNotFoundException.class, () -> actorService.findActor(actor.getId()));
}
@Test
void addPhoto() {
filmService.deleteAllFilms();
actorService.deleteAllActors();
final Actor actor = actorService.addActor("Victor", "Ivanov", "C:\\Users\\parap\\OneDrive\\Рабочий стол\\work\\ferrari.jpg");
Actor findActor = actorService.findActor(actor.getId());
Assertions.assertNotEquals(findActor.getPhoto().length, 0);
}
@Test
void addFilm() {
filmService.findAllFilms();
actorService.deleteAllActors();
final Actor actor = actorService.addActor("Victor", "Ivanov");
final Film film = filmService.addFilm("Terminator 2");
filmService.addActor(film.getId(), actor.getId());
final Actor findActor = actorService.findActor(actor.getId());
Assertions.assertEquals(findActor.getFilms().get(0).getId(), film.getId());
}
}

View File

@ -0,0 +1,94 @@
package ru.ip.labs.labs;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ip.labs.labs.films.models.Actor;
import ru.ip.labs.labs.films.models.Film;
import ru.ip.labs.labs.films.models.Genre;
import ru.ip.labs.labs.films.service.ActorService;
import ru.ip.labs.labs.films.service.FilmsService;
import ru.ip.labs.labs.films.service.GenreService;
import javax.persistence.EntityNotFoundException;
import java.util.List;
@SpringBootTest
public class JpaFilmsTest {
private static final Logger log = LoggerFactory.getLogger(JpaFilmsTest.class);
@Autowired
FilmsService filmService;
@Autowired
GenreService genreService;
@Autowired
ActorService actorService;
@Test
void testFilmCreate() {
filmService.deleteAllFilms();
final Film film = filmService.addFilm("Terminator 2");
log.info(film.toString());
Assertions.assertNotNull(film.getId());
}
@Test
void testFilmReadNotFound() {
filmService.deleteAllFilms();
Assertions.assertThrows(EntityNotFoundException.class, () -> filmService.findFilm(-1L));
}
@Test
void findFilm() {
filmService.deleteAllFilms();
final Film film = filmService.addFilm("Terminator 2");
log.info(film.toString());
final Film findFilm = filmService.findFilm(film.getId());
log.info(findFilm.toString());
Assertions.assertEquals(film.toString(), findFilm.toString());
}
@Test
void updateFilm() {
filmService.deleteAllFilms();
final Film film = filmService.addFilm("Terminator 2");
filmService.updateFilm(film.getId(), "Terminator 3");
final Film findFilm = filmService.findFilm(film.getId());
log.info(findFilm.toString());
Assertions.assertEquals(findFilm.getName(), "Terminator 3");
}
@Test
void testReadAll() {
filmService.deleteAllFilms();
final Film film = filmService.addFilm("Terminator 2");
log.info(film.toString());
final List<Film> films = filmService.findAllFilms();
Assertions.assertEquals(films.size(), 1);
}
@Test
void deleteFilm() {
filmService.deleteAllFilms();
final Film film = filmService.addFilm("Terminator 2");
log.info(film.toString());
filmService.deleteFilm(film.getId());
Assertions.assertThrows(EntityNotFoundException.class, () -> filmService.findFilm(film.getId()));
}
@Test
void addActor() {
filmService.deleteAllFilms();
genreService.deleteAllGenres();
final Film film = filmService.addFilm("Terminator 2");
final Actor actor = actorService.addActor("Victor", "Ivanov");
filmService.addActor(film.getId(), actor.getId());
final Film findFilm = filmService.findFilm(film.getId());
Assertions.assertEquals(findFilm.getActors().get(0).getId(), actor.getId());
}
}

View File

@ -0,0 +1,76 @@
package ru.ip.labs.labs;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ip.labs.labs.films.models.Genre;
import ru.ip.labs.labs.films.service.FilmsService;
import ru.ip.labs.labs.films.service.GenreService;
import javax.persistence.EntityNotFoundException;
import java.util.List;
@SpringBootTest
public class JpaGenresTest {
private static final Logger log = LoggerFactory.getLogger(JpaFilmsTest.class);
@Autowired
FilmsService filmService;
@Autowired
GenreService genreService;
@Test
void testGenreCreate() {
genreService.deleteAllGenres();
final Genre genre = genreService.addGenre("Comedy");
log.info(genre.toString());
Assertions.assertNotNull(genre.getId());
}
@Test
void testGenreReadNotFound() {
genreService.deleteAllGenres();
Assertions.assertThrows(EntityNotFoundException.class, () -> genreService.findGenre(-1L));
}
@Test
void findGenre() {
genreService.deleteAllGenres();
final Genre genre = genreService.addGenre("Comedy");
log.info(genre.toString());
final Genre findGenre = genreService.findGenre(genre.getId());
log.info(findGenre.toString());
Assertions.assertEquals(genre.toString(), findGenre.toString());
}
@Test
void testReadAll() {
genreService.deleteAllGenres();
final Genre genre = genreService.addGenre("Comedy");
log.info(genre.toString());
final List<Genre> genres = genreService.findAllGenres();
Assertions.assertEquals(genres.size(), 1);
}
@Test
void updateGenre() {
genreService.deleteAllGenres();
final Genre genre = genreService.addGenre("Comedy");
genreService.updateGenre(genre.getId(), "Drama");
final Genre findGenre = genreService.findGenre(genre.getId());
log.info(findGenre.toString());
Assertions.assertEquals(findGenre.getName(), "Drama");
}
@Test
void deleteGenre() {
genreService.deleteAllGenres();
final Genre genre = genreService.addGenre("Comedy");
log.info(genre.toString());
genreService.deleteGenre(genre.getId());
Assertions.assertThrows(EntityNotFoundException.class, () -> filmService.findFilm(genre.getId()));
}
}

View File

@ -1,13 +1,79 @@
package ru.ip.labs.labs;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ip.labs.labs.calculator.domain.Calculator;
import ru.ip.labs.labs.calculator.service.CalculatorService;
@SpringBootTest
class LabsApplicationTests {
@Autowired
private CalculatorService calculatorService;
@Test
void contextLoads() {
void testIntSum() {
Integer res = calculatorService.getSum(2, 2, "int");
Assertions.assertEquals(4, res);
}
@Test
void testArraySum() {
String res = calculatorService.getSum("1,2", 2, "array");
Assertions.assertEquals("3,4", res);
}
@Test
void testIntDiff() {
Integer res = calculatorService.getDiff(4, 2, "int");
Assertions.assertEquals(2, res);
}
@Test
void testStringDiff() {
String res = calculatorService.getDiff("hello2", 2, "string");
Assertions.assertEquals("hello", res);
}
@Test
void testArrayDiff() {
String res = calculatorService.getDiff("1,2,3", 2, "array");
Assertions.assertEquals("-1,0,1", res);
}
@Test
void testIntMultiple() {
Integer res = calculatorService.getMultiple(2, 3, "int");
Assertions.assertEquals(6, res);
}
@Test
void testStringMultiple() {
String res = calculatorService.getMultiple("test", 2, "string");
Assertions.assertEquals("testtest", res);
}
@Test
void testArrayMultiple() {
String res = calculatorService.getMultiple("2,3", 2, "array");
Assertions.assertEquals("4,6", res);
}
@Test
void testIntDivide() {
Integer res = calculatorService.getDivide(10, 2, "int");
Assertions.assertEquals(5, res);
}
@Test
void testStringDivide() {
String res = calculatorService.getDivide("test", 2, "string");
Assertions.assertEquals("te", res);
}
@Test
void testArrayDivide() {
String res = calculatorService.getDivide("6,8", 2, "array");
Assertions.assertEquals("3,4", res);
}
@Test
void testErrorErrorWired() {
Assertions.assertThrows(NoSuchBeanDefinitionException.class, () -> calculatorService.getSum(1, 2, "date"));
}
}