Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
69466dca35 | ||
|
c793d802ef | ||
|
e4c17f1642 | ||
|
c7b8f30077 | ||
|
f9febea780 | ||
|
1586beb53b | ||
|
efd20a1796 | ||
|
651d1a95f4 | ||
|
4d916bdfe6 | ||
|
901f388780 | ||
|
e739ceadec | ||
|
995e104e86 | ||
|
e3ddc3f4b3 |
1
.gitignore
vendored
@ -9,6 +9,7 @@ build/
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
17
build.gradle
@ -6,7 +6,7 @@ plugins {
|
||||
|
||||
group = 'ru.ip.labs'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
sourceCompatibility = '11'
|
||||
sourceCompatibility = '17'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@ -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
8235
data.trace.db
Normal file
23
frontend/.gitignore
vendored
Normal 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
26
frontend/data.json
Normal 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
|
||||
}
|
||||
]
|
||||
}
|
@ -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>
|
@ -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
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
25
frontend/public/index.html
Normal 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>
|
25
frontend/public/manifest.json
Normal 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
40
frontend/src/App.js
Normal 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;
|
22
frontend/src/components/Banner.css
Normal 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;
|
||||
}
|
29
frontend/src/components/Banner.jsx
Normal 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>
|
||||
)
|
||||
}
|
51
frontend/src/components/catalogs/CatalogActors.jsx
Normal 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>
|
||||
)
|
||||
}
|
147
frontend/src/components/catalogs/CatalogFilms.jsx
Normal 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>
|
||||
)
|
||||
}
|
46
frontend/src/components/catalogs/CatalogGenres.jsx
Normal 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>
|
||||
)
|
||||
}
|
104
frontend/src/components/common/Catalog.jsx
Normal 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>
|
||||
)
|
||||
}
|
21
frontend/src/components/common/Header.css
Normal 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;
|
||||
}
|
28
frontend/src/components/common/Header.jsx
Normal 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>
|
||||
)
|
||||
}
|
11
frontend/src/components/common/LinksList.jsx
Normal 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>
|
||||
)
|
||||
}
|
21
frontend/src/components/common/Modal.jsx
Normal 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>
|
||||
)
|
||||
}
|
3
frontend/src/components/common/Table.css
Normal file
@ -0,0 +1,3 @@
|
||||
.selected {
|
||||
background: #2150de;
|
||||
}
|
41
frontend/src/components/common/Table.jsx
Normal 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>
|
||||
)
|
||||
}
|
9
frontend/src/components/common/Toolbar.jsx
Normal 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>
|
||||
)
|
||||
}
|
13
frontend/src/components/pages/Catalogs.jsx
Normal 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}/>
|
||||
)
|
||||
}
|
5
frontend/src/components/pages/Contacts.css
Normal file
@ -0,0 +1,5 @@
|
||||
.map__frame {
|
||||
width: 90%;
|
||||
height: 500px;
|
||||
margin-bottom: 30px;
|
||||
}
|
12
frontend/src/components/pages/Contacts.jsx
Normal 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>
|
||||
)
|
||||
}
|
47
frontend/src/components/pages/Film.css
Normal 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;
|
||||
}
|
15
frontend/src/components/pages/Film.jsx
Normal 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>
|
||||
)
|
||||
}
|
36
frontend/src/components/pages/Films.jsx
Normal 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>
|
||||
)
|
||||
}
|
25
frontend/src/components/pages/Home.jsx
Normal 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>
|
||||
)
|
||||
}
|
11
frontend/src/components/pages/Reports.jsx
Normal file
@ -0,0 +1,11 @@
|
||||
import LinksList from "../common/LinksList";
|
||||
|
||||
export default function Reports() {
|
||||
let items = [
|
||||
{text: "фильмы", link: "reportsFilms"},
|
||||
];
|
||||
|
||||
return (
|
||||
<LinksList items={items}/>
|
||||
)
|
||||
}
|
50
frontend/src/components/reports/ReportSelector.jsx
Normal 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>
|
||||
)
|
||||
}
|
26
frontend/src/components/reports/ReportsFilms.jsx
Normal 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
After Width: | Height: | Size: 12 KiB |
BIN
frontend/src/img/2.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
frontend/src/img/3.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
frontend/src/img/4.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
frontend/src/img/5.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
frontend/src/img/play.png
Normal file
After Width: | Height: | Size: 54 KiB |
13
frontend/src/index.css
Normal 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
@ -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();
|
13
frontend/src/reportWebVitals.js
Normal 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;
|
40
frontend/src/services/DataService.js
Normal 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
@ -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.
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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/");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
71
src/main/java/ru/ip/labs/labs/films/dto/ActorDTO.java
Normal 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;
|
||||
}
|
||||
}
|
76
src/main/java/ru/ip/labs/labs/films/dto/FilmDTO.java
Normal 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;
|
||||
}
|
||||
}
|
39
src/main/java/ru/ip/labs/labs/films/dto/GenreDTO.java
Normal 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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
74
src/main/java/ru/ip/labs/labs/films/models/Actor.java
Normal 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;
|
||||
}
|
||||
}
|
96
src/main/java/ru/ip/labs/labs/films/models/Film.java
Normal 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;
|
||||
}
|
||||
}
|
36
src/main/java/ru/ip/labs/labs/films/models/Genre.java
Normal 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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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> {
|
||||
}
|
@ -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);
|
||||
}
|
113
src/main/java/ru/ip/labs/labs/films/service/ActorService.java
Normal 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();
|
||||
}
|
||||
}
|
200
src/main/java/ru/ip/labs/labs/films/service/FilmsService.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
||||
|
23
src/main/resources/static/css/Banner.css
Normal 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;
|
||||
}
|
5
src/main/resources/static/css/Contacts.css
Normal file
@ -0,0 +1,5 @@
|
||||
.map__frame {
|
||||
width: 90%;
|
||||
height: 500px;
|
||||
margin-bottom: 30px;
|
||||
}
|
21
src/main/resources/static/css/Header.css
Normal 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;
|
||||
}
|
3
src/main/resources/static/css/Table.css
Normal file
@ -0,0 +1,3 @@
|
||||
.selected {
|
||||
background: #2150de;
|
||||
}
|
BIN
src/main/resources/static/img/1.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
src/main/resources/static/img/2.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
src/main/resources/static/img/3.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
src/main/resources/static/img/4.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
src/main/resources/static/img/5.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
src/main/resources/static/img/play.png
Normal file
After Width: | Height: | Size: 54 KiB |
114
src/main/resources/templates/actors-catalog.html
Normal 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>
|
14
src/main/resources/templates/catalogs.html
Normal 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>
|
14
src/main/resources/templates/contacts.html
Normal 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>
|
54
src/main/resources/templates/default.html
Normal 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>
|
242
src/main/resources/templates/films-catalog.html
Normal 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>
|
61
src/main/resources/templates/films.html
Normal 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>
|
102
src/main/resources/templates/genres-catalog.html
Normal 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>
|
51
src/main/resources/templates/index.html
Normal 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>
|
106
src/test/java/ru/ip/labs/labs/JpaActorsTest.java
Normal 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());
|
||||
}
|
||||
}
|
94
src/test/java/ru/ip/labs/labs/JpaFilmsTest.java
Normal 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());
|
||||
}
|
||||
}
|
76
src/test/java/ru/ip/labs/labs/JpaGenresTest.java
Normal 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()));
|
||||
}
|
||||
}
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|