From 5109ddbd0f445d2f7383e05012985359a32e7b39 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Sun, 8 Feb 2026 23:04:42 +0300 Subject: [PATCH 01/10] init --- 351003/brezgunov/distcomp/.gitignore | 41 +++ 351003/brezgunov/distcomp/build.gradle.kts | 41 +++ 351003/brezgunov/distcomp/gradlew | 248 ++++++++++++++++++ 351003/brezgunov/distcomp/gradlew.bat | 93 +++++++ 351003/brezgunov/distcomp/settings.gradle.kts | 1 + .../com/distcomp/DistcompApplication.kt | 11 + .../src/main/resources/application.yaml | 3 + .../com/distcomp/DistcompApplicationTests.kt | 13 + 8 files changed, 451 insertions(+) create mode 100644 351003/brezgunov/distcomp/.gitignore create mode 100644 351003/brezgunov/distcomp/build.gradle.kts create mode 100644 351003/brezgunov/distcomp/gradlew create mode 100644 351003/brezgunov/distcomp/gradlew.bat create mode 100644 351003/brezgunov/distcomp/settings.gradle.kts create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/DistcompApplication.kt create mode 100644 351003/brezgunov/distcomp/src/main/resources/application.yaml create mode 100644 351003/brezgunov/distcomp/src/test/kotlin/com/distcomp/DistcompApplicationTests.kt diff --git a/351003/brezgunov/distcomp/.gitignore b/351003/brezgunov/distcomp/.gitignore new file mode 100644 index 000000000..dc67744db --- /dev/null +++ b/351003/brezgunov/distcomp/.gitignore @@ -0,0 +1,41 @@ +HELP.md +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Kotlin ### +.kotlin +/gradle/wrapper/ diff --git a/351003/brezgunov/distcomp/build.gradle.kts b/351003/brezgunov/distcomp/build.gradle.kts new file mode 100644 index 000000000..46202df46 --- /dev/null +++ b/351003/brezgunov/distcomp/build.gradle.kts @@ -0,0 +1,41 @@ +plugins { + kotlin("jvm") version "2.3.0" + kotlin("plugin.spring") version "2.3.0" + id("org.springframework.boot") version "4.0.2" + id("io.spring.dependency-management") version "1.1.7" +} + +group = "com" +version = "0.0.1-SNAPSHOT" +description = "distcomp" + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(25) + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-webmvc") + implementation("org.jetbrains.kotlin:kotlin-reflect") + implementation("tools.jackson.module:jackson-module-kotlin") + testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") +} + +kotlin { + jvmToolchain(25) + + compilerOptions { + freeCompilerArgs.addAll("-Xjsr305=strict", "-Xannotation-default-target=param-property") + } +} + +tasks.withType { + useJUnitPlatform() +} diff --git a/351003/brezgunov/distcomp/gradlew b/351003/brezgunov/distcomp/gradlew new file mode 100644 index 000000000..adff685a0 --- /dev/null +++ b/351003/brezgunov/distcomp/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/351003/brezgunov/distcomp/gradlew.bat b/351003/brezgunov/distcomp/gradlew.bat new file mode 100644 index 000000000..c4bdd3ab8 --- /dev/null +++ b/351003/brezgunov/distcomp/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/351003/brezgunov/distcomp/settings.gradle.kts b/351003/brezgunov/distcomp/settings.gradle.kts new file mode 100644 index 000000000..ce3e13349 --- /dev/null +++ b/351003/brezgunov/distcomp/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "distcomp" diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/DistcompApplication.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/DistcompApplication.kt new file mode 100644 index 000000000..81f898e66 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/DistcompApplication.kt @@ -0,0 +1,11 @@ +package com.distcomp + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@SpringBootApplication +class DistcompApplication + +fun main(args: Array) { + runApplication(*args) +} diff --git a/351003/brezgunov/distcomp/src/main/resources/application.yaml b/351003/brezgunov/distcomp/src/main/resources/application.yaml new file mode 100644 index 000000000..c557ad7a7 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/resources/application.yaml @@ -0,0 +1,3 @@ +spring: + application: + name: 'distcomp'S diff --git a/351003/brezgunov/distcomp/src/test/kotlin/com/distcomp/DistcompApplicationTests.kt b/351003/brezgunov/distcomp/src/test/kotlin/com/distcomp/DistcompApplicationTests.kt new file mode 100644 index 000000000..facba20f7 --- /dev/null +++ b/351003/brezgunov/distcomp/src/test/kotlin/com/distcomp/DistcompApplicationTests.kt @@ -0,0 +1,13 @@ +package com.distcomp + +import org.junit.jupiter.api.Test +import org.springframework.boot.test.context.SpringBootTest + +@SpringBootTest +class DistcompApplicationTests { + + @Test + fun contextLoads() { + } + +} From 160111ca174649be6b340d94f460f70b34e29589 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Sun, 8 Feb 2026 23:43:04 +0300 Subject: [PATCH 02/10] add entities and dtos --- .../com/distcomp/dto/marker/MarkerRequestTo.kt | 6 ++++++ .../com/distcomp/dto/marker/MarkerResponseTo.kt | 7 +++++++ .../com/distcomp/dto/news/NewsRequestTo.kt | 8 ++++++++ .../com/distcomp/dto/news/NewsResponseTo.kt | 17 +++++++++++++++++ .../com/distcomp/dto/notice/NoticeRequestTo.kt | 7 +++++++ .../com/distcomp/dto/notice/NoticeResponseTo.kt | 7 +++++++ .../com/distcomp/dto/user/UserRequestTo.kt | 8 ++++++++ .../com/distcomp/dto/user/UserResponseTo.kt | 7 +++++++ .../main/kotlin/com/distcomp/entity/Marker.kt | 7 +++++++ .../src/main/kotlin/com/distcomp/entity/News.kt | 14 ++++++++++++++ .../main/kotlin/com/distcomp/entity/Notice.kt | 7 +++++++ .../src/main/kotlin/com/distcomp/entity/User.kt | 9 +++++++++ .../src/main/resources/application.yaml | 5 ++++- 13 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt new file mode 100644 index 000000000..a52e6710a --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt @@ -0,0 +1,6 @@ +package com.distcomp.dto.marker + +data class MarkerRequestTo( + var id: Long? = null, + var name: String, +) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt new file mode 100644 index 000000000..885c4819f --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt @@ -0,0 +1,7 @@ +package com.distcomp.dto.marker + +data class MarkerResponseTo( + var id: Long, + var name: String, + var newsId: Long +) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt new file mode 100644 index 000000000..44eebc2be --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt @@ -0,0 +1,8 @@ +package com.distcomp.dto.news + +data class NewsRequestTo ( + var id: Long? = null, + var title: String, + var content: String, + var userId: Long +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt new file mode 100644 index 000000000..4e386b78b --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt @@ -0,0 +1,17 @@ +package com.distcomp.dto.news + +import com.distcomp.dto.marker.MarkerResponseTo +import com.distcomp.dto.notice.NoticeResponseTo +import com.distcomp.dto.user.UserResponseTo +import java.time.LocalDateTime + +data class NewsResponseTo( + var id: Long, + var title: String, + var content: String, + var created: LocalDateTime, + var modified: LocalDateTime, + var user: UserResponseTo, + var notices: MutableList, + var markers: MutableList +) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt new file mode 100644 index 000000000..6f8b784c0 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt @@ -0,0 +1,7 @@ +package com.distcomp.dto.notice + +data class NoticeRequestTo ( + var id: Long? = null, + var newsId: Long, + var content: String +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt new file mode 100644 index 000000000..029b1cb64 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt @@ -0,0 +1,7 @@ +package com.distcomp.dto.notice + +data class NoticeResponseTo ( + var id: Long, + var content: String, + var newsId: Long, +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt new file mode 100644 index 000000000..0cfdab71f --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt @@ -0,0 +1,8 @@ +package com.distcomp.dto.user + +data class UserRequestTo( + var username: String? = null, + var password: String, + var firstname: String, + var lastname: String, +) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt new file mode 100644 index 000000000..c53f2aeb9 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt @@ -0,0 +1,7 @@ +package com.distcomp.dto.user + +data class UserResponseTo ( + var username: String, + var firstname: String, + var lastname: String, +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt new file mode 100644 index 000000000..e36ab5f1b --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt @@ -0,0 +1,7 @@ +package com.distcomp.entity + +class Marker ( + var id: Long, + var name: String, + var news: List +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt new file mode 100644 index 000000000..882384b90 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt @@ -0,0 +1,14 @@ +package com.distcomp.entity + +import java.time.LocalDateTime + +class News( + var id: Long, + var title: String, + var content: String, + var created: LocalDateTime, + var modified: LocalDateTime, + var user: User, + var notices: MutableList, + var markers: MutableList +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt new file mode 100644 index 000000000..6aedb2ca1 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt @@ -0,0 +1,7 @@ +package com.distcomp.entity + +class Notice ( + var id: Long, + var content: String, + var news: News +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt new file mode 100644 index 000000000..e95daa9be --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt @@ -0,0 +1,9 @@ +package com.distcomp.entity + +class User ( + var username: String, + var password: String, + var firstname: String, + var lastname: String, + var list: List +) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/resources/application.yaml b/351003/brezgunov/distcomp/src/main/resources/application.yaml index c557ad7a7..4286d6804 100644 --- a/351003/brezgunov/distcomp/src/main/resources/application.yaml +++ b/351003/brezgunov/distcomp/src/main/resources/application.yaml @@ -1,3 +1,6 @@ spring: application: - name: 'distcomp'S + name: 'distcomp' + +server: + port: 24110 From 22fa688515b8a61f567e090fac6594be62180675 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Sun, 8 Feb 2026 23:54:49 +0300 Subject: [PATCH 03/10] mappers added --- 351003/brezgunov/distcomp/build.gradle.kts | 1 + .../kotlin/com/distcomp/mapper/MarkerMapper.kt | 18 ++++++++++++++++++ .../kotlin/com/distcomp/mapper/NewsMapper.kt | 18 ++++++++++++++++++ .../kotlin/com/distcomp/mapper/NoticeMapper.kt | 18 ++++++++++++++++++ .../kotlin/com/distcomp/mapper/UserMapper.kt | 18 ++++++++++++++++++ 5 files changed, 73 insertions(+) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/UserMapper.kt diff --git a/351003/brezgunov/distcomp/build.gradle.kts b/351003/brezgunov/distcomp/build.gradle.kts index 46202df46..1202223f4 100644 --- a/351003/brezgunov/distcomp/build.gradle.kts +++ b/351003/brezgunov/distcomp/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-webmvc") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("tools.jackson.module:jackson-module-kotlin") + implementation("org.mapstruct:mapstruct:1.7.0.Beta1") testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") testRuntimeOnly("org.junit.platform:junit-platform-launcher") diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt new file mode 100644 index 000000000..3261a2320 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt @@ -0,0 +1,18 @@ +package com.distcomp.mapper + +import com.distcomp.dto.marker.MarkerRequestTo +import com.distcomp.dto.marker.MarkerResponseTo +import com.distcomp.entity.Marker +import org.mapstruct.Mapper +import org.mapstruct.MappingConstants +import org.mapstruct.ReportingPolicy + +@Mapper( + componentModel = MappingConstants.ComponentModel.SPRING, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +interface MarkerMapper { + fun toMarkerResponse(marker: Marker) : MarkerResponseTo + + fun toNewsEntity(markerRequestTo: MarkerRequestTo) : Marker +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt new file mode 100644 index 000000000..e30956678 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt @@ -0,0 +1,18 @@ +package com.distcomp.mapper + +import com.distcomp.dto.news.NewsRequestTo +import com.distcomp.dto.news.NewsResponseTo +import com.distcomp.entity.News +import org.mapstruct.Mapper +import org.mapstruct.MappingConstants +import org.mapstruct.ReportingPolicy + +@Mapper( + componentModel = MappingConstants.ComponentModel.SPRING, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +interface NewsMapper { + fun toNewsResponse(news: News) : NewsResponseTo + + fun toNewsEntity(newsRequestTo: NewsRequestTo) : News +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt new file mode 100644 index 000000000..a2a144455 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt @@ -0,0 +1,18 @@ +package com.distcomp.mapper + +import com.distcomp.dto.notice.NoticeRequestTo +import com.distcomp.dto.notice.NoticeResponseTo +import com.distcomp.entity.Notice +import org.mapstruct.Mapper +import org.mapstruct.MappingConstants +import org.mapstruct.ReportingPolicy + +@Mapper( + componentModel = MappingConstants.ComponentModel.SPRING, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +interface NoticeMapper { + fun toNoticeResponse(notice: Notice) : NoticeResponseTo + + fun toNewsEntity(noticeRequestTo: NoticeRequestTo) : Notice +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/UserMapper.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/UserMapper.kt new file mode 100644 index 000000000..5fb5bb2a4 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/UserMapper.kt @@ -0,0 +1,18 @@ +package com.distcomp.mapper + +import com.distcomp.dto.user.UserRequestTo +import com.distcomp.dto.user.UserResponseTo +import com.distcomp.entity.User +import org.mapstruct.Mapper +import org.mapstruct.MappingConstants +import org.mapstruct.ReportingPolicy + +@Mapper( + componentModel = MappingConstants.ComponentModel.SPRING, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +interface UserMapper { + fun toUserResponse(user: User) : UserResponseTo + + fun toUserEntity(userRequestTo: UserRequestTo) : User +} \ No newline at end of file From d2a81e5387eedc8aef534b55ba3bf4321f65ab34 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Mon, 9 Feb 2026 01:33:19 +0300 Subject: [PATCH 04/10] user repository --- .../repository/user/UserRepository.kt | 9 +++++++ .../repository/user/UserRepositoryInMem.kt | 26 +++++++++++++++++++ .../com/distcomp/service/UserService.kt | 13 ++++++++++ 3 files changed, 48 insertions(+) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt new file mode 100644 index 000000000..5cd7d9720 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt @@ -0,0 +1,9 @@ +package com.distcomp.repository.user + +import com.distcomp.entity.User + +interface UserRepository { + fun save(user: User) + + fun findUserById(id: Long): User? +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt new file mode 100644 index 000000000..c74523e99 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt @@ -0,0 +1,26 @@ +package com.distcomp.repository.user + +import com.distcomp.entity.User +import jakarta.annotation.PostConstruct +import org.springframework.stereotype.Repository +import java.util.concurrent.atomic.AtomicLong + +@Repository +class UserRepositoryInMem : UserRepository { + + private val userMap: MutableMap = mutableMapOf() + private val counter = AtomicLong(0L) + + @PostConstruct + fun init() { + print("init") + } + + override fun save(user: User) { + val counter = counter.incrementAndGet() + } + + override fun findUserById(id: Long): User? { + return userMap[id] + } +} diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt new file mode 100644 index 000000000..243cc0cd4 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt @@ -0,0 +1,13 @@ +package com.distcomp.service + +import com.distcomp.mapper.UserMapper +import org.springframework.stereotype.Service + +@Service +class UserService ( + val userMapper: UserMapper +) { +// fun createUser(): UserResponseTo { +// return UserResponseTo() +// } +} \ No newline at end of file From dd565cf447d52fa8bc5e9eb0392b44815f522b6e Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Mon, 9 Feb 2026 03:55:37 +0300 Subject: [PATCH 05/10] add get user --- 351003/brezgunov/distcomp/build.gradle.kts | 3 +++ 351003/brezgunov/distcomp/gradlew | 12 ++++++---- 351003/brezgunov/distcomp/gradlew.bat | 3 ++- .../com/distcomp/controller/UserController.kt | 23 +++++++++++++++++++ .../distcomp/dto/marker/MarkerRequestTo.kt | 4 ++-- .../distcomp/dto/marker/MarkerResponseTo.kt | 6 ++--- .../com/distcomp/dto/news/NewsRequestTo.kt | 8 +++---- .../com/distcomp/dto/news/NewsResponseTo.kt | 16 ++++++------- .../distcomp/dto/notice/NoticeRequestTo.kt | 6 ++--- .../distcomp/dto/notice/NoticeResponseTo.kt | 6 ++--- .../com/distcomp/dto/user/UserRequestTo.kt | 9 ++++---- .../com/distcomp/dto/user/UserResponseTo.kt | 7 +++--- .../main/kotlin/com/distcomp/entity/User.kt | 5 ++-- .../repository/user/UserRepositoryInMem.kt | 13 ++++------- .../com/distcomp/service/UserService.kt | 15 ++++++++---- .../src/main/resources/application.yaml | 6 +++++ 16 files changed, 93 insertions(+), 49 deletions(-) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt diff --git a/351003/brezgunov/distcomp/build.gradle.kts b/351003/brezgunov/distcomp/build.gradle.kts index 1202223f4..ecefd45dd 100644 --- a/351003/brezgunov/distcomp/build.gradle.kts +++ b/351003/brezgunov/distcomp/build.gradle.kts @@ -1,6 +1,7 @@ plugins { kotlin("jvm") version "2.3.0" kotlin("plugin.spring") version "2.3.0" + kotlin("kapt") version "2.3.0" id("org.springframework.boot") version "4.0.2" id("io.spring.dependency-management") version "1.1.7" } @@ -24,6 +25,8 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("tools.jackson.module:jackson-module-kotlin") implementation("org.mapstruct:mapstruct:1.7.0.Beta1") + implementation("org.springframework.boot:spring-boot-starter-actuator") + kapt("org.mapstruct:mapstruct-processor:1.7.0.Beta1") testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") testRuntimeOnly("org.junit.platform:junit-platform-launcher") diff --git a/351003/brezgunov/distcomp/gradlew b/351003/brezgunov/distcomp/gradlew index adff685a0..f5feea6d6 100644 --- a/351003/brezgunov/distcomp/gradlew +++ b/351003/brezgunov/distcomp/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015 the original authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -86,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -114,6 +115,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -171,6 +173,7 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,14 +206,15 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ "$@" # Stop when "xargs" is not available. diff --git a/351003/brezgunov/distcomp/gradlew.bat b/351003/brezgunov/distcomp/gradlew.bat index c4bdd3ab8..9d21a2183 100644 --- a/351003/brezgunov/distcomp/gradlew.bat +++ b/351003/brezgunov/distcomp/gradlew.bat @@ -70,10 +70,11 @@ goto fail :execute @rem Setup the command line +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt new file mode 100644 index 000000000..f5ff5528c --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt @@ -0,0 +1,23 @@ +package com.distcomp.controller + +import com.distcomp.dto.user.UserRequestTo +import com.distcomp.dto.user.UserResponseTo +import com.distcomp.service.UserService +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/api/{version}/users") +class UserController ( + private val userService: UserService +) { + @PostMapping(version = "1.0") + @ResponseStatus(HttpStatus.CREATED) + fun createUser(@RequestBody userRequestTo: UserRequestTo): UserResponseTo { + return userService.createUser(userRequestTo) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt index a52e6710a..e6901d1ca 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt @@ -1,6 +1,6 @@ package com.distcomp.dto.marker data class MarkerRequestTo( - var id: Long? = null, - var name: String, + val id: Long? = null, + val name: String, ) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt index 885c4819f..2fc05c6b7 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerResponseTo.kt @@ -1,7 +1,7 @@ package com.distcomp.dto.marker data class MarkerResponseTo( - var id: Long, - var name: String, - var newsId: Long + val id: Long, + val name: String, + val newsId: Long ) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt index 44eebc2be..dc48e090b 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt @@ -1,8 +1,8 @@ package com.distcomp.dto.news data class NewsRequestTo ( - var id: Long? = null, - var title: String, - var content: String, - var userId: Long + val id: Long? = null, + val title: String, + val content: String, + val userId: Long ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt index 4e386b78b..27f174a63 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt @@ -6,12 +6,12 @@ import com.distcomp.dto.user.UserResponseTo import java.time.LocalDateTime data class NewsResponseTo( - var id: Long, - var title: String, - var content: String, - var created: LocalDateTime, - var modified: LocalDateTime, - var user: UserResponseTo, - var notices: MutableList, - var markers: MutableList + val id: Long, + val title: String, + val content: String, + val created: LocalDateTime, + val modified: LocalDateTime, + val user: UserResponseTo, + val notices: MutableList, + val markers: MutableList ) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt index 6f8b784c0..107b73b35 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt @@ -1,7 +1,7 @@ package com.distcomp.dto.notice data class NoticeRequestTo ( - var id: Long? = null, - var newsId: Long, - var content: String + val id: Long? = null, + val newsId: Long, + val content: String ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt index 029b1cb64..1dfb88af8 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeResponseTo.kt @@ -1,7 +1,7 @@ package com.distcomp.dto.notice data class NoticeResponseTo ( - var id: Long, - var content: String, - var newsId: Long, + val id: Long, + val content: String, + val newsId: Long, ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt index 0cfdab71f..6a7329984 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt @@ -1,8 +1,9 @@ package com.distcomp.dto.user data class UserRequestTo( - var username: String? = null, - var password: String, - var firstname: String, - var lastname: String, + val id: Long? = null, + val login: String, + val password: String, + val firstname: String, + val lastname: String, ) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt index c53f2aeb9..04061aac9 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserResponseTo.kt @@ -1,7 +1,8 @@ package com.distcomp.dto.user data class UserResponseTo ( - var username: String, - var firstname: String, - var lastname: String, + val id: Long, + val login: String, + val firstname: String, + val lastname: String, ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt index e95daa9be..776bf65dc 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt @@ -1,9 +1,10 @@ package com.distcomp.entity class User ( - var username: String, + var id: Long, + var login: String, var password: String, var firstname: String, var lastname: String, - var list: List + var news: List? ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt index c74523e99..ba6664f4a 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt @@ -3,21 +3,18 @@ package com.distcomp.repository.user import com.distcomp.entity.User import jakarta.annotation.PostConstruct import org.springframework.stereotype.Repository +import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicLong @Repository class UserRepositoryInMem : UserRepository { - - private val userMap: MutableMap = mutableMapOf() + private val userMap = ConcurrentHashMap() private val counter = AtomicLong(0L) - @PostConstruct - fun init() { - print("init") - } - override fun save(user: User) { - val counter = counter.incrementAndGet() + val index = counter.incrementAndGet() + userMap[index] = user + user.id = index } override fun findUserById(id: Long): User? { diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt index 243cc0cd4..c80d2ebcd 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt @@ -1,13 +1,20 @@ package com.distcomp.service +import com.distcomp.dto.user.UserRequestTo +import com.distcomp.dto.user.UserResponseTo import com.distcomp.mapper.UserMapper +import com.distcomp.repository.user.UserRepository +import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service @Service class UserService ( - val userMapper: UserMapper + val userMapper: UserMapper, + @Qualifier("userRepositoryInMem") val userRepository: UserRepository ) { -// fun createUser(): UserResponseTo { -// return UserResponseTo() -// } + fun createUser(userRequestTo: UserRequestTo): UserResponseTo { + val user = userMapper.toUserEntity(userRequestTo) + userRepository.save(user) + return userMapper.toUserResponse(user) + } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/resources/application.yaml b/351003/brezgunov/distcomp/src/main/resources/application.yaml index 4286d6804..f06fdc777 100644 --- a/351003/brezgunov/distcomp/src/main/resources/application.yaml +++ b/351003/brezgunov/distcomp/src/main/resources/application.yaml @@ -1,6 +1,12 @@ spring: application: name: 'distcomp' + mvc: + apiversion: + use: + path-segment: 1 + supported: 1.0, 2.0 + default: 1.0 server: port: 24110 From 919d10d4a25cf79d3b612905a58322a1c00ccd65 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Wed, 11 Feb 2026 18:14:30 +0300 Subject: [PATCH 06/10] user done --- .../distcomp/controller/ControllerAdvice.kt | 19 +++++++++++ .../com/distcomp/controller/UserController.kt | 26 +++++++++++++++ .../com/distcomp/dto/ErrorResponseTo.kt | 6 ++++ .../main/kotlin/com/distcomp/entity/User.kt | 2 +- .../distcomp/exception/AbstractException.kt | 8 +++++ .../exception/UserNotFoundException.kt | 7 ++++ .../repository/user/CrudRepository.kt | 11 +++++++ .../repository/user/UserRepository.kt | 9 ----- .../repository/user/UserRepositoryInMem.kt | 23 ++++++++++--- .../com/distcomp/service/UserService.kt | 33 +++++++++++++++++-- 10 files changed, 127 insertions(+), 17 deletions(-) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/ErrorResponseTo.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/AbstractException.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/UserNotFoundException.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/CrudRepository.kt delete mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt new file mode 100644 index 000000000..0ce797466 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt @@ -0,0 +1,19 @@ +package com.distcomp.controller + +import com.distcomp.dto.ErrorResponseTo +import com.distcomp.exception.AbstractException +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.ExceptionHandler +import org.springframework.web.bind.annotation.RestControllerAdvice + +@RestControllerAdvice +class GlobalExceptionHandler { + @ExceptionHandler(AbstractException::class) + fun handleUserNotFound(e: AbstractException): ResponseEntity { + val error = ErrorResponseTo( + status = e.errorCode.value(), + message = e.errorMsg + ) + return ResponseEntity(error, e.errorCode) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt index f5ff5528c..7c7e6fdf0 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt @@ -4,7 +4,11 @@ import com.distcomp.dto.user.UserRequestTo import com.distcomp.dto.user.UserResponseTo import com.distcomp.service.UserService import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.DeleteMapping +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.PutMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.ResponseStatus @@ -20,4 +24,26 @@ class UserController ( fun createUser(@RequestBody userRequestTo: UserRequestTo): UserResponseTo { return userService.createUser(userRequestTo) } + + @GetMapping("{id}") + fun readUserById(@PathVariable("id") id: Long): UserResponseTo { + return userService.readUserById(id) + } + + @GetMapping + fun findAll(): List { + return userService.readAll() + } + + @PutMapping(version = "1.0") + @ResponseStatus(HttpStatus.OK) + fun updateUser(@RequestBody userRequestTo: UserRequestTo): UserResponseTo { + return userService.updateUser(userRequestTo) + } + + @DeleteMapping(path = ["/{id}"], version = "1.0") + @ResponseStatus(HttpStatus.NO_CONTENT) + fun deleteUser(@PathVariable("id") id: Long) { + userService.removeUserById(id) + } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/ErrorResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/ErrorResponseTo.kt new file mode 100644 index 000000000..e1b9e3029 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/ErrorResponseTo.kt @@ -0,0 +1,6 @@ +package com.distcomp.dto + +data class ErrorResponseTo( + val status: Int, + val message: String, +) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt index 776bf65dc..86fff086f 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt @@ -1,7 +1,7 @@ package com.distcomp.entity class User ( - var id: Long, + var id: Long? = null, var login: String, var password: String, var firstname: String, diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/AbstractException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/AbstractException.kt new file mode 100644 index 000000000..2a9051bb2 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/AbstractException.kt @@ -0,0 +1,8 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +abstract class AbstractException ( + val errorCode: HttpStatus, + val errorMsg: String +) : RuntimeException(errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/UserNotFoundException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/UserNotFoundException.kt new file mode 100644 index 000000000..dda817ebd --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/UserNotFoundException.kt @@ -0,0 +1,7 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class UserNotFoundException ( + errorMsg: String +) : AbstractException(HttpStatus.NOT_FOUND, errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/CrudRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/CrudRepository.kt new file mode 100644 index 000000000..8b0b061cb --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/CrudRepository.kt @@ -0,0 +1,11 @@ +package com.distcomp.repository.user + +interface CrudRepository { + fun save(user: T) + + fun findById(id: Long): T? + + fun findAll(): List + + fun removeById(id: Long) +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt deleted file mode 100644 index 5cd7d9720..000000000 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepository.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.distcomp.repository.user - -import com.distcomp.entity.User - -interface UserRepository { - fun save(user: User) - - fun findUserById(id: Long): User? -} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt index ba6664f4a..9986eb96c 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt @@ -1,23 +1,36 @@ package com.distcomp.repository.user import com.distcomp.entity.User -import jakarta.annotation.PostConstruct import org.springframework.stereotype.Repository import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicLong @Repository -class UserRepositoryInMem : UserRepository { +class UserRepositoryInMem : CrudRepository { private val userMap = ConcurrentHashMap() private val counter = AtomicLong(0L) override fun save(user: User) { - val index = counter.incrementAndGet() + val index = if (user.id == null) { + val newId = counter.incrementAndGet() + user.id = newId + newId + } else { + user.id!! + } + userMap[index] = user - user.id = index } - override fun findUserById(id: Long): User? { + override fun findById(id: Long): User? { return userMap[id] } + + override fun findAll(): List { + return userMap.values.toList() + } + + override fun removeById(id: Long) { + userMap.remove(id) + } } diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt index c80d2ebcd..f8761118d 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt @@ -2,19 +2,48 @@ package com.distcomp.service import com.distcomp.dto.user.UserRequestTo import com.distcomp.dto.user.UserResponseTo +import com.distcomp.entity.User +import com.distcomp.exception.UserNotFoundException import com.distcomp.mapper.UserMapper -import com.distcomp.repository.user.UserRepository +import com.distcomp.repository.user.CrudRepository import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service @Service class UserService ( val userMapper: UserMapper, - @Qualifier("userRepositoryInMem") val userRepository: UserRepository + @Qualifier("userRepositoryInMem") val userRepository: CrudRepository ) { fun createUser(userRequestTo: UserRequestTo): UserResponseTo { val user = userMapper.toUserEntity(userRequestTo) userRepository.save(user) return userMapper.toUserResponse(user) } + + fun readUserById(id: Long): UserResponseTo { + val user = userRepository.findById(id) ?: throw UserNotFoundException("User not found") + return userMapper.toUserResponse(user) + } + + fun readAll(): List { + return userRepository.findAll().map { userMapper.toUserResponse(it) } + } + + fun updateUser(userRequestTo: UserRequestTo): UserResponseTo { + if (userRequestTo.id == null || userRepository.findById(userRequestTo.id) == null) { + throw UserNotFoundException("User not found") + } + + val user = userMapper.toUserEntity(userRequestTo) + userRepository.save(user) + return userMapper.toUserResponse(user) + } + + fun removeUserById(id: Long) { + if (userRepository.findById(id) == null) { + throw UserNotFoundException("User not found") + } + + userRepository.removeById(id) + } } \ No newline at end of file From ba0422770215a3a121f2b0b25667decf265fc602 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Fri, 13 Feb 2026 18:07:43 +0300 Subject: [PATCH 07/10] add news, notices --- .../distcomp/controller/ControllerAdvice.kt | 2 +- .../com/distcomp/controller/NewsController.kt | 50 ++++++++++++++++ .../distcomp/controller/NoticeController.kt | 44 ++++++++++++++ .../com/distcomp/dto/news/NewsResponseTo.kt | 7 +-- .../main/kotlin/com/distcomp/entity/News.kt | 10 ++-- .../main/kotlin/com/distcomp/entity/Notice.kt | 2 +- .../exception/NewsForbiddenException.kt | 7 +++ .../exception/NewsNotFoundException.kt | 7 +++ .../exception/NoticeNotFoundException.kt | 7 +++ .../distcomp/exception/ValidationException.kt | 7 +++ .../kotlin/com/distcomp/mapper/NewsMapper.kt | 11 +++- .../com/distcomp/mapper/NoticeMapper.kt | 4 +- .../repository/{user => }/CrudRepository.kt | 4 +- .../repository/NewsRepositoryInMem.kt | 37 ++++++++++++ .../repository/NoticeRepositoryInMem.kt | 36 +++++++++++ .../{user => }/UserRepositoryInMem.kt | 2 +- .../com/distcomp/service/NewsService.kt | 60 +++++++++++++++++++ .../com/distcomp/service/NoticeService.kt | 57 ++++++++++++++++++ .../com/distcomp/service/UserService.kt | 2 +- 19 files changed, 336 insertions(+), 20 deletions(-) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsForbiddenException.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsNotFoundException.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NoticeNotFoundException.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/ValidationException.kt rename 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/{user => }/CrudRepository.kt (67%) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt rename 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/{user => }/UserRepositoryInMem.kt (95%) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt index 0ce797466..3741f242f 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/ControllerAdvice.kt @@ -14,6 +14,6 @@ class GlobalExceptionHandler { status = e.errorCode.value(), message = e.errorMsg ) - return ResponseEntity(error, e.errorCode) + return ResponseEntity.status(e.errorCode).body(error) } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt new file mode 100644 index 000000000..3ce81f995 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt @@ -0,0 +1,50 @@ +package com.distcomp.controller + +import com.distcomp.dto.news.NewsRequestTo +import com.distcomp.dto.news.NewsResponseTo +import com.distcomp.service.NewsService +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.DeleteMapping +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.ResponseStatus +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/api/{version}/news") +class NewsController ( + private val newsService: NewsService +) { + @PostMapping(version = "1.0") + @ResponseStatus(HttpStatus.CREATED) + fun createUser(@RequestBody newsRequestTo: NewsRequestTo): NewsResponseTo { + return newsService.createNews(newsRequestTo) + } + + @GetMapping("{id}") + fun readUserById(@PathVariable("id") id: Long): NewsResponseTo { + return newsService.readNewsById(id) + } + + @GetMapping + fun findAll(): List { + return newsService.readAll() + } + + @PutMapping(path = ["/{id}", ""], version = "1.0") + @ResponseStatus(HttpStatus.OK) + fun updateUser(@RequestBody newsRequestTo: NewsRequestTo, + @PathVariable("id") userId: Long?): NewsResponseTo { + return newsService.updateNews(newsRequestTo, userId) + } + + @DeleteMapping(path = ["/{id}"], version = "1.0") + @ResponseStatus(HttpStatus.NO_CONTENT) + fun deleteUser(@PathVariable("id") id: Long) { + newsService.removeNewsById(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt new file mode 100644 index 000000000..333d8fc47 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt @@ -0,0 +1,44 @@ +package com.distcomp.controller + +import com.distcomp.dto.notice.NoticeRequestTo +import com.distcomp.dto.notice.NoticeResponseTo +import com.distcomp.service.NoticeService +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/api/{version}/notices") +class NoticeController( + private val noticeService: NoticeService +) { + @PostMapping(version = "1.0") + @ResponseStatus(HttpStatus.CREATED) + fun createNotice(@RequestBody noticeRequestTo: NoticeRequestTo): NoticeResponseTo { + return noticeService.createNotice(noticeRequestTo) + } + + @GetMapping("{id}") + fun readNoticeById(@PathVariable("id") id: Long): NoticeResponseTo { + return noticeService.readNoticeById(id) + } + + @GetMapping + fun findAll(): List { + return noticeService.readAll() + } + + @PutMapping(path = ["/{id}", ""], version = "1.0") + @ResponseStatus(HttpStatus.OK) + fun updateNotice( + @RequestBody noticeRequestTo: NoticeRequestTo, + @PathVariable("id") id: Long? + ): NoticeResponseTo { + return noticeService.updateNotice(noticeRequestTo, id) + } + + @DeleteMapping(path = ["/{id}"], version = "1.0") + @ResponseStatus(HttpStatus.NO_CONTENT) + fun deleteNotice(@PathVariable("id") id: Long) { + noticeService.removeNoticeById(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt index 27f174a63..ab55a3403 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsResponseTo.kt @@ -1,8 +1,5 @@ package com.distcomp.dto.news -import com.distcomp.dto.marker.MarkerResponseTo -import com.distcomp.dto.notice.NoticeResponseTo -import com.distcomp.dto.user.UserResponseTo import java.time.LocalDateTime data class NewsResponseTo( @@ -11,7 +8,5 @@ data class NewsResponseTo( val content: String, val created: LocalDateTime, val modified: LocalDateTime, - val user: UserResponseTo, - val notices: MutableList, - val markers: MutableList + val userId: Long ) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt index 882384b90..055e73049 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt @@ -3,12 +3,10 @@ package com.distcomp.entity import java.time.LocalDateTime class News( - var id: Long, + var id: Long? = null, var title: String, var content: String, - var created: LocalDateTime, - var modified: LocalDateTime, - var user: User, - var notices: MutableList, - var markers: MutableList + var created: LocalDateTime = LocalDateTime.now(), + var modified: LocalDateTime = LocalDateTime.now(), + var user: User? = null ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt index 6aedb2ca1..a4c831855 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt @@ -3,5 +3,5 @@ package com.distcomp.entity class Notice ( var id: Long, var content: String, - var news: News + var news: News? = null ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsForbiddenException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsForbiddenException.kt new file mode 100644 index 000000000..d0fe886b6 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsForbiddenException.kt @@ -0,0 +1,7 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class NewsForbiddenException ( + errorMsg: String +) : AbstractException(HttpStatus.FORBIDDEN, errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsNotFoundException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsNotFoundException.kt new file mode 100644 index 000000000..f792fbe87 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsNotFoundException.kt @@ -0,0 +1,7 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class NewsNotFoundException ( + errorMsg: String +) : AbstractException(HttpStatus.NOT_FOUND, errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NoticeNotFoundException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NoticeNotFoundException.kt new file mode 100644 index 000000000..6b75e59bb --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NoticeNotFoundException.kt @@ -0,0 +1,7 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class NoticeNotFoundException ( + errorMsg: String +) : AbstractException(HttpStatus.NOT_FOUND, errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/ValidationException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/ValidationException.kt new file mode 100644 index 000000000..2b7e7ec74 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/ValidationException.kt @@ -0,0 +1,7 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class ValidationException ( + errorMsg: String +) : AbstractException(HttpStatus.BAD_REQUEST, errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt index e30956678..e0e863938 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NewsMapper.kt @@ -4,15 +4,24 @@ import com.distcomp.dto.news.NewsRequestTo import com.distcomp.dto.news.NewsResponseTo import com.distcomp.entity.News import org.mapstruct.Mapper +import org.mapstruct.Mapping import org.mapstruct.MappingConstants import org.mapstruct.ReportingPolicy +import java.time.LocalDateTime @Mapper( componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE ) interface NewsMapper { + @Mapping(target = "userId", source = "user.id") fun toNewsResponse(news: News) : NewsResponseTo - fun toNewsEntity(newsRequestTo: NewsRequestTo) : News + fun toNewsEntity(newsRequestTo: NewsRequestTo): News { + return News( + id = newsRequestTo.id, + title = newsRequestTo.title, + content = newsRequestTo.content + ) + } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt index a2a144455..4d6fb8531 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/NoticeMapper.kt @@ -4,6 +4,7 @@ import com.distcomp.dto.notice.NoticeRequestTo import com.distcomp.dto.notice.NoticeResponseTo import com.distcomp.entity.Notice import org.mapstruct.Mapper +import org.mapstruct.Mapping import org.mapstruct.MappingConstants import org.mapstruct.ReportingPolicy @@ -12,7 +13,8 @@ import org.mapstruct.ReportingPolicy unmappedTargetPolicy = ReportingPolicy.IGNORE ) interface NoticeMapper { + @Mapping(source = "news.id", target = "newsId") fun toNoticeResponse(notice: Notice) : NoticeResponseTo - fun toNewsEntity(noticeRequestTo: NoticeRequestTo) : Notice + fun toNoticeEntity(noticeRequestTo: NoticeRequestTo) : Notice } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/CrudRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/CrudRepository.kt similarity index 67% rename from 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/CrudRepository.kt rename to 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/CrudRepository.kt index 8b0b061cb..e5627c2ce 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/CrudRepository.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/CrudRepository.kt @@ -1,7 +1,7 @@ -package com.distcomp.repository.user +package com.distcomp.repository interface CrudRepository { - fun save(user: T) + fun save(entity: T) fun findById(id: Long): T? diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt new file mode 100644 index 000000000..2b9b2d67d --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt @@ -0,0 +1,37 @@ +package com.distcomp.repository + +import com.distcomp.entity.News +import org.springframework.stereotype.Repository +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicLong +import kotlin.collections.set + +@Repository +class NewsRepositoryInMem : CrudRepository { + private val newsMap = ConcurrentHashMap() + private val counter = AtomicLong(0L) + + override fun save(news: News) { + val index = if (news.id == null) { + val newId = counter.incrementAndGet() + news.id = newId + newId + } else { + news.id!! + } + + newsMap[index] = news + } + + override fun findById(id: Long): News? { + return newsMap[id] + } + + override fun findAll(): List { + return newsMap.values.toList() + } + + override fun removeById(id: Long) { + newsMap.remove(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt new file mode 100644 index 000000000..4afe7a029 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt @@ -0,0 +1,36 @@ +package com.distcomp.repository + +import com.distcomp.entity.Notice +import org.springframework.stereotype.Repository +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicLong + +@Repository +class NoticeRepositoryInMem : CrudRepository { + private val noticeMap = ConcurrentHashMap() + private val counter = AtomicLong(0L) + + override fun save(notice: Notice) { + val index = if (notice.id == null) { + val newId = counter.incrementAndGet() + notice.id = newId + newId + } else { + notice.id!! + } + + noticeMap[index] = notice + } + + override fun findById(id: Long): Notice? { + return noticeMap[id] + } + + override fun findAll(): List { + return noticeMap.values.toList() + } + + override fun removeById(id: Long) { + noticeMap.remove(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepositoryInMem.kt similarity index 95% rename from 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt rename to 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepositoryInMem.kt index 9986eb96c..aa003afae 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/user/UserRepositoryInMem.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepositoryInMem.kt @@ -1,4 +1,4 @@ -package com.distcomp.repository.user +package com.distcomp.repository import com.distcomp.entity.User import org.springframework.stereotype.Repository diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt new file mode 100644 index 000000000..e859a06e2 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt @@ -0,0 +1,60 @@ +package com.distcomp.service + +import com.distcomp.dto.news.NewsRequestTo +import com.distcomp.dto.news.NewsResponseTo +import com.distcomp.entity.News +import com.distcomp.entity.User +import com.distcomp.exception.NewsNotFoundException +import com.distcomp.exception.ValidationException +import com.distcomp.mapper.NewsMapper +import com.distcomp.repository.CrudRepository +import org.springframework.stereotype.Service + +@Service +class NewsService ( + val newsMapper: NewsMapper, + val newsRepository: CrudRepository, + val userRepository: CrudRepository +) { + fun createNews(newsRequestTo: NewsRequestTo): NewsResponseTo { + val news = newsMapper.toNewsEntity(newsRequestTo) + newsRepository.save(news) + val user = userRepository.findById(newsRequestTo.userId) + news.user = user + return newsMapper.toNewsResponse(news) + } + + fun readNewsById(id: Long): NewsResponseTo { + val user = newsRepository.findById(id) ?: throw NewsNotFoundException("User not found") + return newsMapper.toNewsResponse(user) + } + + fun readAll(): List { + return newsRepository.findAll().map { newsMapper.toNewsResponse(it) } + } + + fun updateNews(newsRequestTo: NewsRequestTo, newsId: Long?): NewsResponseTo { + if (newsId == null || newsRepository.findById(newsId) == null) { + throw NewsNotFoundException("User not found") + } + + if (newsRequestTo.title.length < 2) { + throw ValidationException("New title is too short") + } + + val news = newsMapper.toNewsEntity(newsRequestTo) + news.id = newsId + newsRepository.save(news) + val user = userRepository.findById(newsRequestTo.userId) + news.user = user + return newsMapper.toNewsResponse(news) + } + + fun removeNewsById(id: Long) { + if (newsRepository.findById(id) == null) { + throw NewsNotFoundException("News not found") + } + + newsRepository.removeById(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt new file mode 100644 index 000000000..2ca96ac17 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt @@ -0,0 +1,57 @@ +package com.distcomp.service + +import com.distcomp.dto.notice.NoticeRequestTo +import com.distcomp.dto.notice.NoticeResponseTo +import com.distcomp.entity.News +import com.distcomp.entity.Notice +import com.distcomp.exception.NewsNotFoundException +import com.distcomp.exception.NoticeNotFoundException +import com.distcomp.mapper.NoticeMapper +import com.distcomp.repository.CrudRepository +import org.springframework.stereotype.Service + +@Service +class NoticeService( + val noticeMapper: NoticeMapper, + val noticeRepository: CrudRepository, + val newsRepository: CrudRepository +) { + fun createNotice(noticeRequestTo: NoticeRequestTo): NoticeResponseTo { + val notice = noticeMapper.toNoticeEntity(noticeRequestTo) + noticeRepository.save(notice) + val news = newsRepository.findById(noticeRequestTo.newsId) + notice.news = news ?: throw NewsNotFoundException("News not found") + return noticeMapper.toNoticeResponse(notice) + } + + fun readNoticeById(id: Long): NoticeResponseTo { + val notice = noticeRepository.findById(id) + ?: throw NoticeNotFoundException("Notice with id $id not found") + return noticeMapper.toNoticeResponse(notice) + } + + fun readAll(): List { + return noticeRepository.findAll().map { noticeMapper.toNoticeResponse(it) } + } + + fun updateNotice(noticeRequestTo: NoticeRequestTo, noticeId: Long?): NoticeResponseTo { + if (noticeId == null || noticeRepository.findById(noticeId) == null) { + throw NoticeNotFoundException("Notice with id $noticeId not found") + } + + val notice = noticeMapper.toNoticeEntity(noticeRequestTo) + notice.id = noticeId + noticeRepository.save(notice) + val news = newsRepository.findById(noticeRequestTo.newsId) + notice.news = news ?: throw NewsNotFoundException("News not found") + return noticeMapper.toNoticeResponse(notice) + } + + fun removeNoticeById(id: Long) { + if (noticeRepository.findById(id) == null) { + throw NoticeNotFoundException("Notice with id $id not found") + } + + noticeRepository.removeById(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt index f8761118d..cac4dcc48 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt @@ -5,7 +5,7 @@ import com.distcomp.dto.user.UserResponseTo import com.distcomp.entity.User import com.distcomp.exception.UserNotFoundException import com.distcomp.mapper.UserMapper -import com.distcomp.repository.user.CrudRepository +import com.distcomp.repository.CrudRepository import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service From 5d0aa54c6580907e7d1f0cf6eb4e499ae517e0b5 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Fri, 13 Feb 2026 18:22:04 +0300 Subject: [PATCH 08/10] add markers --- .../distcomp/controller/MarkerController.kt | 44 ++++++++++++++++ .../main/kotlin/com/distcomp/entity/Marker.kt | 1 - .../exception/MarkerNotFoundException.kt | 7 +++ .../com/distcomp/mapper/MarkerMapper.kt | 2 +- .../repository/MarkerRepositoryInMem.kt | 36 +++++++++++++ .../com/distcomp/service/MarkerService.kt | 50 +++++++++++++++++++ .../com/distcomp/service/NoticeService.kt | 2 + 7 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/MarkerNotFoundException.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt new file mode 100644 index 000000000..bd2c03ce0 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt @@ -0,0 +1,44 @@ +package com.distcomp.controller + +import com.distcomp.dto.marker.MarkerRequestTo +import com.distcomp.dto.marker.MarkerResponseTo +import com.distcomp.service.MarkerService +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/api/{version}/markers") +class MarkerController( + private val markerService: MarkerService +) { + @PostMapping(version = "1.0") + @ResponseStatus(HttpStatus.CREATED) + fun createMarker(@RequestBody markerRequestTo: MarkerRequestTo): MarkerResponseTo { + return markerService.createMarker(markerRequestTo) + } + + @GetMapping("{id}") + fun readMarkerById(@PathVariable("id") id: Long): MarkerResponseTo { + return markerService.readMarkerById(id) + } + + @GetMapping + fun findAll(): List { + return markerService.readAll() + } + + @PutMapping(path = ["/{id}", ""], version = "1.0") + @ResponseStatus(HttpStatus.OK) + fun updateMarker( + @RequestBody markerRequestTo: MarkerRequestTo, + @PathVariable("id") id: Long? + ): MarkerResponseTo { + return markerService.updateMarker(markerRequestTo, id) + } + + @DeleteMapping(path = ["/{id}"], version = "1.0") + @ResponseStatus(HttpStatus.NO_CONTENT) + fun deleteMarker(@PathVariable("id") id: Long) { + markerService.removeMarkerById(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt index e36ab5f1b..368a76c77 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt @@ -3,5 +3,4 @@ package com.distcomp.entity class Marker ( var id: Long, var name: String, - var news: List ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/MarkerNotFoundException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/MarkerNotFoundException.kt new file mode 100644 index 000000000..75a534883 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/MarkerNotFoundException.kt @@ -0,0 +1,7 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class MarkerNotFoundException ( + errorMsg: String +) : AbstractException(HttpStatus.NOT_FOUND, errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt index 3261a2320..3e9395cd0 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/mapper/MarkerMapper.kt @@ -14,5 +14,5 @@ import org.mapstruct.ReportingPolicy interface MarkerMapper { fun toMarkerResponse(marker: Marker) : MarkerResponseTo - fun toNewsEntity(markerRequestTo: MarkerRequestTo) : Marker + fun toMarkerEntity(markerRequestTo: MarkerRequestTo) : Marker } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt new file mode 100644 index 000000000..d112e78a4 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt @@ -0,0 +1,36 @@ +package com.distcomp.repository + +import com.distcomp.entity.Marker +import org.springframework.stereotype.Repository +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.atomic.AtomicLong + +@Repository +class MarkerRepositoryInMem : CrudRepository { + private val markerMap = ConcurrentHashMap() + private val counter = AtomicLong(0L) + + override fun save(entity: Marker) { + val index = if (entity.id == null) { + val newId = counter.incrementAndGet() + entity.id = newId + newId + } else { + entity.id!! + } + + markerMap[index] = entity + } + + override fun findById(id: Long): Marker? { + return markerMap[id] + } + + override fun findAll(): List { + return markerMap.values.toList() + } + + override fun removeById(id: Long) { + markerMap.remove(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt new file mode 100644 index 000000000..b04507d23 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt @@ -0,0 +1,50 @@ +package com.distcomp.service + +import com.distcomp.dto.marker.MarkerRequestTo +import com.distcomp.dto.marker.MarkerResponseTo +import com.distcomp.entity.Marker +import com.distcomp.exception.MarkerNotFoundException +import com.distcomp.mapper.MarkerMapper +import com.distcomp.repository.CrudRepository +import org.springframework.stereotype.Service + +@Service +class MarkerService( + val markerMapper: MarkerMapper, + val markerRepository: CrudRepository +) { + fun createMarker(markerRequestTo: MarkerRequestTo): MarkerResponseTo { + val marker = markerMapper.toMarkerEntity(markerRequestTo) + markerRepository.save(marker) + return markerMapper.toMarkerResponse(marker) + } + + fun readMarkerById(id: Long): MarkerResponseTo { + val marker = markerRepository.findById(id) + ?: throw MarkerNotFoundException("Marker with id $id not found") + return markerMapper.toMarkerResponse(marker) + } + + fun readAll(): List { + return markerRepository.findAll().map { markerMapper.toMarkerResponse(it) } + } + + fun updateMarker(markerRequestTo: MarkerRequestTo, markerId: Long?): MarkerResponseTo { + if (markerId == null || markerRepository.findById(markerId) == null) { + throw MarkerNotFoundException("Marker with id $markerId not found") + } + + val marker = markerMapper.toMarkerEntity(markerRequestTo) + marker.id = markerId + + markerRepository.save(marker) + return markerMapper.toMarkerResponse(marker) + } + + fun removeMarkerById(id: Long) { + if (markerRepository.findById(id) == null) { + throw MarkerNotFoundException("Marker with id $id not found") + } + markerRepository.removeById(id) + } +} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt index 2ca96ac17..a9f322ed5 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt @@ -42,8 +42,10 @@ class NoticeService( val notice = noticeMapper.toNoticeEntity(noticeRequestTo) notice.id = noticeId noticeRepository.save(notice) + val news = newsRepository.findById(noticeRequestTo.newsId) notice.news = news ?: throw NewsNotFoundException("News not found") + return noticeMapper.toNoticeResponse(notice) } From 83b6312de38e23c5fa376361d6e8c29fe02701e5 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Thu, 19 Feb 2026 17:32:21 +0300 Subject: [PATCH 09/10] add jpa --- 351003/brezgunov/distcomp/build.gradle.kts | 4 ++ .../distcomp/controller/MarkerController.kt | 5 ++- .../com/distcomp/controller/NewsController.kt | 5 ++- .../distcomp/controller/NoticeController.kt | 5 ++- .../com/distcomp/controller/UserController.kt | 5 ++- .../distcomp/dto/marker/MarkerRequestTo.kt | 5 +++ .../com/distcomp/dto/news/NewsRequestTo.kt | 9 +++++ .../distcomp/dto/notice/NoticeRequestTo.kt | 7 ++++ .../com/distcomp/dto/user/UserRequestTo.kt | 11 ++++++ .../main/kotlin/com/distcomp/entity/Marker.kt | 10 ++++- .../main/kotlin/com/distcomp/entity/News.kt | 9 +++++ .../main/kotlin/com/distcomp/entity/Notice.kt | 10 ++++- .../main/kotlin/com/distcomp/entity/User.kt | 11 +++++- .../com/distcomp/repository/CrudRepository.kt | 11 ------ .../distcomp/repository/MarkerRepository.kt | 6 +++ .../repository/MarkerRepositoryInMem.kt | 36 ------------------ .../com/distcomp/repository/NewsRepository.kt | 6 +++ .../repository/NewsRepositoryInMem.kt | 37 ------------------- .../distcomp/repository/NoticeRepository.kt | 6 +++ .../repository/NoticeRepositoryInMem.kt | 36 ------------------ .../com/distcomp/repository/UserRepository.kt | 6 +++ .../repository/UserRepositoryInMem.kt | 36 ------------------ .../com/distcomp/service/MarkerService.kt | 14 +++---- .../com/distcomp/service/NewsService.kt | 28 +++++++------- .../com/distcomp/service/NoticeService.kt | 22 +++++------ .../com/distcomp/service/UserService.kt | 17 ++++----- .../src/main/resources/application.yaml | 12 ++++++ 27 files changed, 160 insertions(+), 209 deletions(-) delete mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/CrudRepository.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepository.kt delete mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt delete mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepository.kt delete mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt delete mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepositoryInMem.kt diff --git a/351003/brezgunov/distcomp/build.gradle.kts b/351003/brezgunov/distcomp/build.gradle.kts index ecefd45dd..1e9ce0ee5 100644 --- a/351003/brezgunov/distcomp/build.gradle.kts +++ b/351003/brezgunov/distcomp/build.gradle.kts @@ -1,6 +1,7 @@ plugins { kotlin("jvm") version "2.3.0" kotlin("plugin.spring") version "2.3.0" + kotlin("plugin.jpa") version "2.3.0" kotlin("kapt") version "2.3.0" id("org.springframework.boot") version "4.0.2" id("io.spring.dependency-management") version "1.1.7" @@ -22,11 +23,14 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-webmvc") + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-validation") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("tools.jackson.module:jackson-module-kotlin") implementation("org.mapstruct:mapstruct:1.7.0.Beta1") implementation("org.springframework.boot:spring-boot-starter-actuator") kapt("org.mapstruct:mapstruct-processor:1.7.0.Beta1") + runtimeOnly("org.postgresql:postgresql") testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") testRuntimeOnly("org.junit.platform:junit-platform-launcher") diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt index bd2c03ce0..14adf5076 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/MarkerController.kt @@ -3,6 +3,7 @@ package com.distcomp.controller import com.distcomp.dto.marker.MarkerRequestTo import com.distcomp.dto.marker.MarkerResponseTo import com.distcomp.service.MarkerService +import jakarta.validation.Valid import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* @@ -13,7 +14,7 @@ class MarkerController( ) { @PostMapping(version = "1.0") @ResponseStatus(HttpStatus.CREATED) - fun createMarker(@RequestBody markerRequestTo: MarkerRequestTo): MarkerResponseTo { + fun createMarker(@Valid @RequestBody markerRequestTo: MarkerRequestTo): MarkerResponseTo { return markerService.createMarker(markerRequestTo) } @@ -30,7 +31,7 @@ class MarkerController( @PutMapping(path = ["/{id}", ""], version = "1.0") @ResponseStatus(HttpStatus.OK) fun updateMarker( - @RequestBody markerRequestTo: MarkerRequestTo, + @Valid @RequestBody markerRequestTo: MarkerRequestTo, @PathVariable("id") id: Long? ): MarkerResponseTo { return markerService.updateMarker(markerRequestTo, id) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt index 3ce81f995..acd918acd 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NewsController.kt @@ -3,6 +3,7 @@ package com.distcomp.controller import com.distcomp.dto.news.NewsRequestTo import com.distcomp.dto.news.NewsResponseTo import com.distcomp.service.NewsService +import jakarta.validation.Valid import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping @@ -21,7 +22,7 @@ class NewsController ( ) { @PostMapping(version = "1.0") @ResponseStatus(HttpStatus.CREATED) - fun createUser(@RequestBody newsRequestTo: NewsRequestTo): NewsResponseTo { + fun createUser(@Valid @RequestBody newsRequestTo: NewsRequestTo): NewsResponseTo { return newsService.createNews(newsRequestTo) } @@ -37,7 +38,7 @@ class NewsController ( @PutMapping(path = ["/{id}", ""], version = "1.0") @ResponseStatus(HttpStatus.OK) - fun updateUser(@RequestBody newsRequestTo: NewsRequestTo, + fun updateUser(@Valid @RequestBody newsRequestTo: NewsRequestTo, @PathVariable("id") userId: Long?): NewsResponseTo { return newsService.updateNews(newsRequestTo, userId) } diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt index 333d8fc47..a615a820d 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/NoticeController.kt @@ -3,6 +3,7 @@ package com.distcomp.controller import com.distcomp.dto.notice.NoticeRequestTo import com.distcomp.dto.notice.NoticeResponseTo import com.distcomp.service.NoticeService +import jakarta.validation.Valid import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* @@ -13,7 +14,7 @@ class NoticeController( ) { @PostMapping(version = "1.0") @ResponseStatus(HttpStatus.CREATED) - fun createNotice(@RequestBody noticeRequestTo: NoticeRequestTo): NoticeResponseTo { + fun createNotice(@Valid @RequestBody noticeRequestTo: NoticeRequestTo): NoticeResponseTo { return noticeService.createNotice(noticeRequestTo) } @@ -30,7 +31,7 @@ class NoticeController( @PutMapping(path = ["/{id}", ""], version = "1.0") @ResponseStatus(HttpStatus.OK) fun updateNotice( - @RequestBody noticeRequestTo: NoticeRequestTo, + @Valid @RequestBody noticeRequestTo: NoticeRequestTo, @PathVariable("id") id: Long? ): NoticeResponseTo { return noticeService.updateNotice(noticeRequestTo, id) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt index 7c7e6fdf0..cdff60dd4 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/controller/UserController.kt @@ -3,6 +3,7 @@ package com.distcomp.controller import com.distcomp.dto.user.UserRequestTo import com.distcomp.dto.user.UserResponseTo import com.distcomp.service.UserService +import jakarta.validation.Valid import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.DeleteMapping import org.springframework.web.bind.annotation.GetMapping @@ -21,7 +22,7 @@ class UserController ( ) { @PostMapping(version = "1.0") @ResponseStatus(HttpStatus.CREATED) - fun createUser(@RequestBody userRequestTo: UserRequestTo): UserResponseTo { + fun createUser(@Valid @RequestBody userRequestTo: UserRequestTo): UserResponseTo { return userService.createUser(userRequestTo) } @@ -37,7 +38,7 @@ class UserController ( @PutMapping(version = "1.0") @ResponseStatus(HttpStatus.OK) - fun updateUser(@RequestBody userRequestTo: UserRequestTo): UserResponseTo { + fun updateUser(@Valid @RequestBody userRequestTo: UserRequestTo): UserResponseTo { return userService.updateUser(userRequestTo) } diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt index e6901d1ca..9c48764e3 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/marker/MarkerRequestTo.kt @@ -1,6 +1,11 @@ package com.distcomp.dto.marker +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size + data class MarkerRequestTo( val id: Long? = null, + @field:NotBlank + @field:Size(min = 3, max = 32) val name: String, ) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt index dc48e090b..54fbefe93 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt @@ -1,8 +1,17 @@ package com.distcomp.dto.news +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.NotNull +import jakarta.validation.constraints.Size + data class NewsRequestTo ( val id: Long? = null, + @field:NotBlank + @field:Size(min = 3, max = 64) val title: String, + @field:NotBlank + @field:Size(min = 4, max = 2048) val content: String, + @field:NotNull val userId: Long ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt index 107b73b35..fa01454e8 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/notice/NoticeRequestTo.kt @@ -1,7 +1,14 @@ package com.distcomp.dto.notice +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.NotNull +import jakarta.validation.constraints.Size + data class NoticeRequestTo ( val id: Long? = null, + @field:NotNull val newsId: Long, + @field:NotBlank + @field:Size(min = 4, max = 2048) val content: String ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt index 6a7329984..6163471c3 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/user/UserRequestTo.kt @@ -1,9 +1,20 @@ package com.distcomp.dto.user +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size + data class UserRequestTo( val id: Long? = null, + @field:NotBlank + @field:Size(min = 2, max = 64) val login: String, + @field:NotBlank + @field:Size(min = 8, max = 128) val password: String, + @field:NotBlank + @field:Size(min = 2, max = 64) val firstname: String, + @field:NotBlank + @field:Size(min = 2, max = 64) val lastname: String, ) diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt index 368a76c77..b78cc1da1 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt @@ -1,6 +1,14 @@ package com.distcomp.entity -class Marker ( +import jakarta.persistence.* +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size + +@Entity +@Table(name = "tbl_marker") +class Marker( + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) var id: Long, var name: String, ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt index 055e73049..1c76cfe62 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt @@ -1,12 +1,21 @@ package com.distcomp.entity +import jakarta.persistence.* +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Size import java.time.LocalDateTime +@Entity +@Table(name = "tbl_news") class News( + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) var id: Long? = null, var title: String, var content: String, var created: LocalDateTime = LocalDateTime.now(), var modified: LocalDateTime = LocalDateTime.now(), + @ManyToOne + @JoinColumn(name = "user_id") var user: User? = null ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt index a4c831855..ac4d57527 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Notice.kt @@ -1,7 +1,15 @@ package com.distcomp.entity -class Notice ( +import jakarta.persistence.* + +@Entity +@Table(name = "tbl_notice") +class Notice( + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) var id: Long, var content: String, + @ManyToOne + @JoinColumn(name = "news_id") var news: News? = null ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt index 86fff086f..3e2873996 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/User.kt @@ -1,10 +1,17 @@ package com.distcomp.entity -class User ( +import jakarta.persistence.* + +@Entity +@Table(name = "tbl_user") +class User( + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) var id: Long? = null, var login: String, var password: String, var firstname: String, var lastname: String, - var news: List? + @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL]) + var news: MutableList? = null ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/CrudRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/CrudRepository.kt deleted file mode 100644 index e5627c2ce..000000000 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/CrudRepository.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.distcomp.repository - -interface CrudRepository { - fun save(entity: T) - - fun findById(id: Long): T? - - fun findAll(): List - - fun removeById(id: Long) -} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepository.kt new file mode 100644 index 000000000..412866252 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepository.kt @@ -0,0 +1,6 @@ +package com.distcomp.repository + +import com.distcomp.entity.Marker +import org.springframework.data.jpa.repository.JpaRepository + +interface MarkerRepository : JpaRepository diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt deleted file mode 100644 index d112e78a4..000000000 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/MarkerRepositoryInMem.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.distcomp.repository - -import com.distcomp.entity.Marker -import org.springframework.stereotype.Repository -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicLong - -@Repository -class MarkerRepositoryInMem : CrudRepository { - private val markerMap = ConcurrentHashMap() - private val counter = AtomicLong(0L) - - override fun save(entity: Marker) { - val index = if (entity.id == null) { - val newId = counter.incrementAndGet() - entity.id = newId - newId - } else { - entity.id!! - } - - markerMap[index] = entity - } - - override fun findById(id: Long): Marker? { - return markerMap[id] - } - - override fun findAll(): List { - return markerMap.values.toList() - } - - override fun removeById(id: Long) { - markerMap.remove(id) - } -} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt new file mode 100644 index 000000000..3b2989fe2 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt @@ -0,0 +1,6 @@ +package com.distcomp.repository + +import com.distcomp.entity.News +import org.springframework.data.jpa.repository.JpaRepository + +interface NewsRepository : JpaRepository diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt deleted file mode 100644 index 2b9b2d67d..000000000 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepositoryInMem.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.distcomp.repository - -import com.distcomp.entity.News -import org.springframework.stereotype.Repository -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicLong -import kotlin.collections.set - -@Repository -class NewsRepositoryInMem : CrudRepository { - private val newsMap = ConcurrentHashMap() - private val counter = AtomicLong(0L) - - override fun save(news: News) { - val index = if (news.id == null) { - val newId = counter.incrementAndGet() - news.id = newId - newId - } else { - news.id!! - } - - newsMap[index] = news - } - - override fun findById(id: Long): News? { - return newsMap[id] - } - - override fun findAll(): List { - return newsMap.values.toList() - } - - override fun removeById(id: Long) { - newsMap.remove(id) - } -} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepository.kt new file mode 100644 index 000000000..4e4dcb529 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepository.kt @@ -0,0 +1,6 @@ +package com.distcomp.repository + +import com.distcomp.entity.Notice +import org.springframework.data.jpa.repository.JpaRepository + +interface NoticeRepository : JpaRepository diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt deleted file mode 100644 index 4afe7a029..000000000 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NoticeRepositoryInMem.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.distcomp.repository - -import com.distcomp.entity.Notice -import org.springframework.stereotype.Repository -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicLong - -@Repository -class NoticeRepositoryInMem : CrudRepository { - private val noticeMap = ConcurrentHashMap() - private val counter = AtomicLong(0L) - - override fun save(notice: Notice) { - val index = if (notice.id == null) { - val newId = counter.incrementAndGet() - notice.id = newId - newId - } else { - notice.id!! - } - - noticeMap[index] = notice - } - - override fun findById(id: Long): Notice? { - return noticeMap[id] - } - - override fun findAll(): List { - return noticeMap.values.toList() - } - - override fun removeById(id: Long) { - noticeMap.remove(id) - } -} \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt new file mode 100644 index 000000000..4b1613550 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt @@ -0,0 +1,6 @@ +package com.distcomp.repository + +import com.distcomp.entity.User +import org.springframework.data.jpa.repository.JpaRepository + +interface UserRepository : JpaRepository diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepositoryInMem.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepositoryInMem.kt deleted file mode 100644 index aa003afae..000000000 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepositoryInMem.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.distcomp.repository - -import com.distcomp.entity.User -import org.springframework.stereotype.Repository -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.atomic.AtomicLong - -@Repository -class UserRepositoryInMem : CrudRepository { - private val userMap = ConcurrentHashMap() - private val counter = AtomicLong(0L) - - override fun save(user: User) { - val index = if (user.id == null) { - val newId = counter.incrementAndGet() - user.id = newId - newId - } else { - user.id!! - } - - userMap[index] = user - } - - override fun findById(id: Long): User? { - return userMap[id] - } - - override fun findAll(): List { - return userMap.values.toList() - } - - override fun removeById(id: Long) { - userMap.remove(id) - } -} diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt index b04507d23..076dde323 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt @@ -2,16 +2,16 @@ package com.distcomp.service import com.distcomp.dto.marker.MarkerRequestTo import com.distcomp.dto.marker.MarkerResponseTo -import com.distcomp.entity.Marker import com.distcomp.exception.MarkerNotFoundException import com.distcomp.mapper.MarkerMapper -import com.distcomp.repository.CrudRepository +import com.distcomp.repository.MarkerRepository +import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service @Service class MarkerService( val markerMapper: MarkerMapper, - val markerRepository: CrudRepository + val markerRepository: MarkerRepository ) { fun createMarker(markerRequestTo: MarkerRequestTo): MarkerResponseTo { val marker = markerMapper.toMarkerEntity(markerRequestTo) @@ -20,7 +20,7 @@ class MarkerService( } fun readMarkerById(id: Long): MarkerResponseTo { - val marker = markerRepository.findById(id) + val marker = markerRepository.findByIdOrNull(id) ?: throw MarkerNotFoundException("Marker with id $id not found") return markerMapper.toMarkerResponse(marker) } @@ -30,7 +30,7 @@ class MarkerService( } fun updateMarker(markerRequestTo: MarkerRequestTo, markerId: Long?): MarkerResponseTo { - if (markerId == null || markerRepository.findById(markerId) == null) { + if (markerId == null || markerRepository.findByIdOrNull(markerId) == null) { throw MarkerNotFoundException("Marker with id $markerId not found") } @@ -42,9 +42,9 @@ class MarkerService( } fun removeMarkerById(id: Long) { - if (markerRepository.findById(id) == null) { + if (markerRepository.findByIdOrNull(id) == null) { throw MarkerNotFoundException("Marker with id $id not found") } - markerRepository.removeById(id) + markerRepository.deleteById(id) } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt index e859a06e2..6560b582b 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt @@ -2,31 +2,31 @@ package com.distcomp.service import com.distcomp.dto.news.NewsRequestTo import com.distcomp.dto.news.NewsResponseTo -import com.distcomp.entity.News -import com.distcomp.entity.User import com.distcomp.exception.NewsNotFoundException import com.distcomp.exception.ValidationException import com.distcomp.mapper.NewsMapper -import com.distcomp.repository.CrudRepository +import com.distcomp.repository.NewsRepository +import com.distcomp.repository.UserRepository +import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service @Service -class NewsService ( +class NewsService( val newsMapper: NewsMapper, - val newsRepository: CrudRepository, - val userRepository: CrudRepository + val newsRepository: NewsRepository, + val userRepository: UserRepository ) { fun createNews(newsRequestTo: NewsRequestTo): NewsResponseTo { val news = newsMapper.toNewsEntity(newsRequestTo) - newsRepository.save(news) - val user = userRepository.findById(newsRequestTo.userId) + val user = userRepository.findByIdOrNull(newsRequestTo.userId) news.user = user + newsRepository.save(news) return newsMapper.toNewsResponse(news) } fun readNewsById(id: Long): NewsResponseTo { - val user = newsRepository.findById(id) ?: throw NewsNotFoundException("User not found") - return newsMapper.toNewsResponse(user) + val news = newsRepository.findByIdOrNull(id) ?: throw NewsNotFoundException("User not found") + return newsMapper.toNewsResponse(news) } fun readAll(): List { @@ -34,7 +34,7 @@ class NewsService ( } fun updateNews(newsRequestTo: NewsRequestTo, newsId: Long?): NewsResponseTo { - if (newsId == null || newsRepository.findById(newsId) == null) { + if (newsId == null || newsRepository.findByIdOrNull(newsId) == null) { throw NewsNotFoundException("User not found") } @@ -45,16 +45,16 @@ class NewsService ( val news = newsMapper.toNewsEntity(newsRequestTo) news.id = newsId newsRepository.save(news) - val user = userRepository.findById(newsRequestTo.userId) + val user = userRepository.findByIdOrNull(newsRequestTo.userId) news.user = user return newsMapper.toNewsResponse(news) } fun removeNewsById(id: Long) { - if (newsRepository.findById(id) == null) { + if (newsRepository.findByIdOrNull(id) == null) { throw NewsNotFoundException("News not found") } - newsRepository.removeById(id) + newsRepository.deleteById(id) } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt index a9f322ed5..49a0c8abc 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt @@ -2,30 +2,30 @@ package com.distcomp.service import com.distcomp.dto.notice.NoticeRequestTo import com.distcomp.dto.notice.NoticeResponseTo -import com.distcomp.entity.News -import com.distcomp.entity.Notice import com.distcomp.exception.NewsNotFoundException import com.distcomp.exception.NoticeNotFoundException import com.distcomp.mapper.NoticeMapper -import com.distcomp.repository.CrudRepository +import com.distcomp.repository.NewsRepository +import com.distcomp.repository.NoticeRepository +import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service @Service class NoticeService( val noticeMapper: NoticeMapper, - val noticeRepository: CrudRepository, - val newsRepository: CrudRepository + val noticeRepository: NoticeRepository, + val newsRepository: NewsRepository ) { fun createNotice(noticeRequestTo: NoticeRequestTo): NoticeResponseTo { val notice = noticeMapper.toNoticeEntity(noticeRequestTo) noticeRepository.save(notice) - val news = newsRepository.findById(noticeRequestTo.newsId) + val news = newsRepository.findByIdOrNull(noticeRequestTo.newsId) notice.news = news ?: throw NewsNotFoundException("News not found") return noticeMapper.toNoticeResponse(notice) } fun readNoticeById(id: Long): NoticeResponseTo { - val notice = noticeRepository.findById(id) + val notice = noticeRepository.findByIdOrNull(id) ?: throw NoticeNotFoundException("Notice with id $id not found") return noticeMapper.toNoticeResponse(notice) } @@ -35,7 +35,7 @@ class NoticeService( } fun updateNotice(noticeRequestTo: NoticeRequestTo, noticeId: Long?): NoticeResponseTo { - if (noticeId == null || noticeRepository.findById(noticeId) == null) { + if (noticeId == null || noticeRepository.findByIdOrNull(noticeId) == null) { throw NoticeNotFoundException("Notice with id $noticeId not found") } @@ -43,17 +43,17 @@ class NoticeService( notice.id = noticeId noticeRepository.save(notice) - val news = newsRepository.findById(noticeRequestTo.newsId) + val news = newsRepository.findByIdOrNull(noticeRequestTo.newsId) notice.news = news ?: throw NewsNotFoundException("News not found") return noticeMapper.toNoticeResponse(notice) } fun removeNoticeById(id: Long) { - if (noticeRepository.findById(id) == null) { + if (noticeRepository.findByIdOrNull(id) == null) { throw NoticeNotFoundException("Notice with id $id not found") } - noticeRepository.removeById(id) + noticeRepository.deleteById(id) } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt index cac4dcc48..b84e8e260 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt @@ -2,17 +2,16 @@ package com.distcomp.service import com.distcomp.dto.user.UserRequestTo import com.distcomp.dto.user.UserResponseTo -import com.distcomp.entity.User import com.distcomp.exception.UserNotFoundException import com.distcomp.mapper.UserMapper -import com.distcomp.repository.CrudRepository -import org.springframework.beans.factory.annotation.Qualifier +import com.distcomp.repository.UserRepository +import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service @Service -class UserService ( +class UserService( val userMapper: UserMapper, - @Qualifier("userRepositoryInMem") val userRepository: CrudRepository + val userRepository: UserRepository ) { fun createUser(userRequestTo: UserRequestTo): UserResponseTo { val user = userMapper.toUserEntity(userRequestTo) @@ -21,7 +20,7 @@ class UserService ( } fun readUserById(id: Long): UserResponseTo { - val user = userRepository.findById(id) ?: throw UserNotFoundException("User not found") + val user = userRepository.findByIdOrNull(id) ?: throw UserNotFoundException("User not found") return userMapper.toUserResponse(user) } @@ -30,7 +29,7 @@ class UserService ( } fun updateUser(userRequestTo: UserRequestTo): UserResponseTo { - if (userRequestTo.id == null || userRepository.findById(userRequestTo.id) == null) { + if (userRequestTo.id == null || userRepository.findByIdOrNull(userRequestTo.id) == null) { throw UserNotFoundException("User not found") } @@ -40,10 +39,10 @@ class UserService ( } fun removeUserById(id: Long) { - if (userRepository.findById(id) == null) { + if (userRepository.findByIdOrNull(id) == null) { throw UserNotFoundException("User not found") } - userRepository.removeById(id) + userRepository.deleteById(id) } } \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/resources/application.yaml b/351003/brezgunov/distcomp/src/main/resources/application.yaml index f06fdc777..4297e9698 100644 --- a/351003/brezgunov/distcomp/src/main/resources/application.yaml +++ b/351003/brezgunov/distcomp/src/main/resources/application.yaml @@ -7,6 +7,18 @@ spring: path-segment: 1 supported: 1.0, 2.0 default: 1.0 + datasource: + url: jdbc:postgresql://localhost:5432/distcomp + username: postgres + password: postgres + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: update + show-sql: true + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect server: port: 24110 From e2385d078fdf0df48923029538427dbf51d1eba0 Mon Sep 17 00:00:00 2001 From: Yury Brazgunou Date: Thu, 26 Feb 2026 15:02:32 +0300 Subject: [PATCH 10/10] add duplication checks --- .../com/distcomp/dto/news/NewsRequestTo.kt | 4 ++- .../main/kotlin/com/distcomp/entity/Marker.kt | 4 +-- .../main/kotlin/com/distcomp/entity/News.kt | 4 ++- .../exception/DuplicateUserException.kt | 6 +++++ .../exception/NewsTitleDuplicateException.kt | 6 +++++ .../com/distcomp/repository/NewsRepository.kt | 4 ++- .../com/distcomp/repository/UserRepository.kt | 4 ++- .../com/distcomp/service/MarkerService.kt | 4 +++ .../com/distcomp/service/NewsService.kt | 25 +++++++++++++++++-- .../com/distcomp/service/NoticeService.kt | 8 ++++-- .../com/distcomp/service/UserService.kt | 9 +++++++ 11 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/DuplicateUserException.kt create mode 100644 351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsTitleDuplicateException.kt diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt index 54fbefe93..895de7009 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/dto/news/NewsRequestTo.kt @@ -1,5 +1,6 @@ package com.distcomp.dto.news +import com.distcomp.dto.marker.MarkerRequestTo import jakarta.validation.constraints.NotBlank import jakarta.validation.constraints.NotNull import jakarta.validation.constraints.Size @@ -13,5 +14,6 @@ data class NewsRequestTo ( @field:Size(min = 4, max = 2048) val content: String, @field:NotNull - val userId: Long + val userId: Long, + val markers: List?, ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt index b78cc1da1..83b63a658 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/Marker.kt @@ -1,14 +1,12 @@ package com.distcomp.entity import jakarta.persistence.* -import jakarta.validation.constraints.NotBlank -import jakarta.validation.constraints.Size @Entity @Table(name = "tbl_marker") class Marker( @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) - var id: Long, + var id: Long = 0, var name: String, ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt index 1c76cfe62..de31acaaf 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/entity/News.kt @@ -17,5 +17,7 @@ class News( var modified: LocalDateTime = LocalDateTime.now(), @ManyToOne @JoinColumn(name = "user_id") - var user: User? = null + var user: User? = null, + @OneToMany(cascade = [(CascadeType.ALL)], orphanRemoval = true) + var markers: MutableList = mutableListOf(), ) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/DuplicateUserException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/DuplicateUserException.kt new file mode 100644 index 000000000..58ed08564 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/DuplicateUserException.kt @@ -0,0 +1,6 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class DuplicateUserException(errorMsg: String) : + AbstractException(HttpStatus.FORBIDDEN, errorMsg) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsTitleDuplicateException.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsTitleDuplicateException.kt new file mode 100644 index 000000000..6575aa0c0 --- /dev/null +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/exception/NewsTitleDuplicateException.kt @@ -0,0 +1,6 @@ +package com.distcomp.exception + +import org.springframework.http.HttpStatus + +class NewsTitleDuplicateException (errorMessage: String) + : AbstractException(HttpStatus.FORBIDDEN, errorMessage) \ No newline at end of file diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt index 3b2989fe2..f6655b107 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/NewsRepository.kt @@ -3,4 +3,6 @@ package com.distcomp.repository import com.distcomp.entity.News import org.springframework.data.jpa.repository.JpaRepository -interface NewsRepository : JpaRepository +interface NewsRepository : JpaRepository { + fun existsByTitle(title: String): Boolean +} diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt index 4b1613550..dcc344a3a 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/repository/UserRepository.kt @@ -3,4 +3,6 @@ package com.distcomp.repository import com.distcomp.entity.User import org.springframework.data.jpa.repository.JpaRepository -interface UserRepository : JpaRepository +interface UserRepository : JpaRepository { + fun existsByLogin(login: String): Boolean +} diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt index 076dde323..2c4e422b2 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/MarkerService.kt @@ -7,12 +7,14 @@ import com.distcomp.mapper.MarkerMapper import com.distcomp.repository.MarkerRepository import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class MarkerService( val markerMapper: MarkerMapper, val markerRepository: MarkerRepository ) { + @Transactional fun createMarker(markerRequestTo: MarkerRequestTo): MarkerResponseTo { val marker = markerMapper.toMarkerEntity(markerRequestTo) markerRepository.save(marker) @@ -29,6 +31,7 @@ class MarkerService( return markerRepository.findAll().map { markerMapper.toMarkerResponse(it) } } + @Transactional fun updateMarker(markerRequestTo: MarkerRequestTo, markerId: Long?): MarkerResponseTo { if (markerId == null || markerRepository.findByIdOrNull(markerId) == null) { throw MarkerNotFoundException("Marker with id $markerId not found") @@ -41,6 +44,7 @@ class MarkerService( return markerMapper.toMarkerResponse(marker) } + @Transactional fun removeMarkerById(id: Long) { if (markerRepository.findByIdOrNull(id) == null) { throw MarkerNotFoundException("Marker with id $id not found") diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt index 6560b582b..9229ef2ab 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NewsService.kt @@ -2,24 +2,43 @@ package com.distcomp.service import com.distcomp.dto.news.NewsRequestTo import com.distcomp.dto.news.NewsResponseTo +import com.distcomp.entity.Marker import com.distcomp.exception.NewsNotFoundException +import com.distcomp.exception.NewsTitleDuplicateException +import com.distcomp.exception.UserNotFoundException import com.distcomp.exception.ValidationException import com.distcomp.mapper.NewsMapper +import com.distcomp.repository.MarkerRepository import com.distcomp.repository.NewsRepository import com.distcomp.repository.UserRepository import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class NewsService( val newsMapper: NewsMapper, val newsRepository: NewsRepository, - val userRepository: UserRepository + val userRepository: UserRepository, + val markerRepository: MarkerRepository ) { + @Transactional fun createNews(newsRequestTo: NewsRequestTo): NewsResponseTo { + if (newsRepository.existsByTitle(newsRequestTo.title)) { + throw NewsTitleDuplicateException("Title already exists") + } + val news = newsMapper.toNewsEntity(newsRequestTo) val user = userRepository.findByIdOrNull(newsRequestTo.userId) + ?: throw UserNotFoundException("User not found") news.user = user + + if (newsRequestTo.markers != null) { + for (markerName in newsRequestTo.markers) { + news.markers.add(Marker(name = markerName)) + } + } + newsRepository.save(news) return newsMapper.toNewsResponse(news) } @@ -33,6 +52,7 @@ class NewsService( return newsRepository.findAll().map { newsMapper.toNewsResponse(it) } } + @Transactional fun updateNews(newsRequestTo: NewsRequestTo, newsId: Long?): NewsResponseTo { if (newsId == null || newsRepository.findByIdOrNull(newsId) == null) { throw NewsNotFoundException("User not found") @@ -44,12 +64,13 @@ class NewsService( val news = newsMapper.toNewsEntity(newsRequestTo) news.id = newsId - newsRepository.save(news) val user = userRepository.findByIdOrNull(newsRequestTo.userId) news.user = user + newsRepository.save(news) return newsMapper.toNewsResponse(news) } + @Transactional fun removeNewsById(id: Long) { if (newsRepository.findByIdOrNull(id) == null) { throw NewsNotFoundException("News not found") diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt index 49a0c8abc..55425d5d4 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/NoticeService.kt @@ -9,6 +9,7 @@ import com.distcomp.repository.NewsRepository import com.distcomp.repository.NoticeRepository import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class NoticeService( @@ -16,11 +17,12 @@ class NoticeService( val noticeRepository: NoticeRepository, val newsRepository: NewsRepository ) { + @Transactional fun createNotice(noticeRequestTo: NoticeRequestTo): NoticeResponseTo { val notice = noticeMapper.toNoticeEntity(noticeRequestTo) - noticeRepository.save(notice) val news = newsRepository.findByIdOrNull(noticeRequestTo.newsId) notice.news = news ?: throw NewsNotFoundException("News not found") + noticeRepository.save(notice) return noticeMapper.toNoticeResponse(notice) } @@ -34,6 +36,7 @@ class NoticeService( return noticeRepository.findAll().map { noticeMapper.toNoticeResponse(it) } } + @Transactional fun updateNotice(noticeRequestTo: NoticeRequestTo, noticeId: Long?): NoticeResponseTo { if (noticeId == null || noticeRepository.findByIdOrNull(noticeId) == null) { throw NoticeNotFoundException("Notice with id $noticeId not found") @@ -41,14 +44,15 @@ class NoticeService( val notice = noticeMapper.toNoticeEntity(noticeRequestTo) notice.id = noticeId - noticeRepository.save(notice) val news = newsRepository.findByIdOrNull(noticeRequestTo.newsId) notice.news = news ?: throw NewsNotFoundException("News not found") + noticeRepository.save(notice) return noticeMapper.toNoticeResponse(notice) } + @Transactional fun removeNoticeById(id: Long) { if (noticeRepository.findByIdOrNull(id) == null) { throw NoticeNotFoundException("Notice with id $id not found") diff --git a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt index b84e8e260..0544adb9b 100644 --- a/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt +++ b/351003/brezgunov/distcomp/src/main/kotlin/com/distcomp/service/UserService.kt @@ -2,18 +2,25 @@ package com.distcomp.service import com.distcomp.dto.user.UserRequestTo import com.distcomp.dto.user.UserResponseTo +import com.distcomp.exception.DuplicateUserException import com.distcomp.exception.UserNotFoundException import com.distcomp.mapper.UserMapper import com.distcomp.repository.UserRepository import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class UserService( val userMapper: UserMapper, val userRepository: UserRepository ) { + @Transactional fun createUser(userRequestTo: UserRequestTo): UserResponseTo { + if (userRepository.existsByLogin(userRequestTo.login)) { + throw DuplicateUserException("User with login already exists") + } + val user = userMapper.toUserEntity(userRequestTo) userRepository.save(user) return userMapper.toUserResponse(user) @@ -28,6 +35,7 @@ class UserService( return userRepository.findAll().map { userMapper.toUserResponse(it) } } + @Transactional fun updateUser(userRequestTo: UserRequestTo): UserResponseTo { if (userRequestTo.id == null || userRepository.findByIdOrNull(userRequestTo.id) == null) { throw UserNotFoundException("User not found") @@ -38,6 +46,7 @@ class UserService( return userMapper.toUserResponse(user) } + @Transactional fun removeUserById(id: Long) { if (userRepository.findByIdOrNull(id) == null) { throw UserNotFoundException("User not found")