Initial commit

parents
Pipeline #1834 canceled with stages
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
\ No newline at end of file
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
FROM openjdk:21
EXPOSE 9090
ADD target/docker-demo-app-two.jar docker-demo-app-two.jar
ENTRYPOINT ["java", "-jar", "/docker-demo-app-two.jar"]
\ No newline at end of file
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.2.0
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "$(uname)" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
else
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=$(java-config --jre-home)
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink)
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
if $darwin ; then
javaHome="$(dirname "\"$javaExecutable\"")"
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
else
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
fi
javaHome="$(dirname "\"$javaExecutable\"")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
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
else
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=$(cd "$wdir/.." || exit 1; pwd)
fi
# end of workaround
done
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
# Remove \r in case we run on Windows within Git Bash
# and check out the repository with auto CRLF management
# enabled. Otherwise, we may read lines that are delimited with
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
# splitting rules.
tr -s '\r\n' ' ' < "$1"
fi
}
log() {
if [ "$MVNW_VERBOSE" = true ]; then
printf '%s\n' "$1"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
log "$MAVEN_PROJECTBASEDIR"
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
if [ -r "$wrapperJarPath" ]; then
log "Found $wrapperJarPath"
else
log "Couldn't find $wrapperJarPath, downloading it ..."
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
fi
while IFS="=" read -r key value; do
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
safeValue=$(echo "$value" | tr -d '\r')
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
log "Downloading from: $wrapperUrl"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
fi
if command -v wget > /dev/null; then
log "Found wget ... using wget"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
log "Found curl ... using curl"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
fi
else
log "Falling back to using Java to download"
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=$(cygpath --path --windows "$javaSource")
javaClass=$(cygpath --path --windows "$javaClass")
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
log " - Compiling MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/javac" "$javaSource")
fi
if [ -e "$javaClass" ]; then
log " - Running MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
wrapperSha256Sum=""
while IFS="=" read -r key value; do
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
if [ -n "$wrapperSha256Sum" ]; then
wrapperSha256Result=false
if command -v sha256sum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
elif command -v shasum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
exit 1
fi
if [ $wrapperSha256Result = false ]; then
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
exit 1
fi
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. 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,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.2.0
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
SET WRAPPER_SHA_256_SUM=""
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
)
IF NOT %WRAPPER_SHA_256_SUM%=="" (
powershell -Command "&{"^
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
" exit 1;"^
"}"^
"}"
if ERRORLEVEL 1 goto error
)
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.treinaweb</groupId>
<artifactId>twjobs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>twjobs</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
<modelmapper.version>3.0.0</modelmapper.version>
<jjwt.version>0.12.5</jjwt.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${modelmapper.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.treinaweb</groupId>
<artifactId>twjobs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>twjobs</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
<modelmapper.version>3.0.0</modelmapper.version>
<jjwt.version>0.12.5</jjwt.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${modelmapper.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<finalName>docker-demo-app-two</finalName>
</build>
</project>
POST {{baseUrl}}/api/auth/register
Content-Type: application/json
{
"name": "AVMakers",
"email": "contato@avmakers.com.br",
"password": "senha@123",
"role": "COMPANY"
}
###
POST {{baseUrl}}/api/auth/login
Content-Type: application/json
{
"email": "contato@treinaweb.com.br",
"password": "senha@123"
}
###
POST {{baseUrl}}/api/auth/refresh
Content-Type: application/json
{
"refreshToken": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjbGV5c29uQG1haWwuY29tIiwiaWF0IjoxNzA4NjU3NDQ2LCJleHAiOjE3MDg2NjEwNDZ9.SlJsXW12JHobn-O7JcUKl7O840ddJrp0769sIN94W2hISWwPjJmHNhpj5NxkH3prKkLlVpW3egu5zELIYfcNlA"
}
GET {{baseUrl}}/api/jobs
###
GET {{baseUrl}}/api/jobs/1
###
POST {{baseUrl}}/api/jobs
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjb250YXRvQGF2bWFrZXJzLmNvbS5iciIsImlhdCI6MTcwODY2MjM1NSwiZXhwIjoxNzA4NjY1OTU1fQ.CJ84nx92_MDuaRiZhW3cic2rqlcz247SISbB-AcakFO5T2kYVM5tU50K8u8TER3td7Y-lcH-16_W9i7kg_kwog
{
"title": "Desenvolvedor Java e Spring",
"description": "Vaga para um desenvolvedor Java e Spring",
"location": "São Paulo",
"level": "MID_LEVEL",
"salary": 7500,
"type": "FULL_TIME",
"skills": [1, 2]
}
###
PUT {{baseUrl}}/api/jobs/1
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjb250YXRvQGF2bWFrZXJzLmNvbS5iciIsImlhdCI6MTcwODY2MjM1NSwiZXhwIjoxNzA4NjY1OTU1fQ.CJ84nx92_MDuaRiZhW3cic2rqlcz247SISbB-AcakFO5T2kYVM5tU50K8u8TER3td7Y-lcH-16_W9i7kg_kwog
{
"title": "Desenvolvedor Back-end Java",
"description": "Vaga para um desenvolvedor que saiba Java e Spring",
"company": "TreinaWeb",
"location": "São Paulo",
"type": "FULL_TIME",
"level": "SENIOR",
"salary": 15000.00,
"skills": [
1,
2,
10
]
}
###
DELETE {{baseUrl}}/api/jobs/3
###
GET {{baseUrl}}/api/jobs/2/skills
###
POST {{baseUrl}}/api/jobs/1/apply
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjbGV5c29uQG1haWwuY29tIiwiaWF0IjoxNzA4NjYyNTgwLCJleHAiOjE3MDg2NjYxODB9.pcB13nFkuUy5lc_rqm8xhfTdP97oknWBhBestwiuMbEUp4diI9QNTeFMW2sHzJM4Hzu3K8IeUhoGNVgPXwk6SQ
GET {{baseUrl}}/api/skills
###
GET {{baseUrl}}/api/skills/1
###
POST {{baseUrl}}/api/skills
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjb250YXRvQHRyZWluYXdlYi5jb20uYnIiLCJpYXQiOjE3MDg2NTg4MjgsImV4cCI6MTcwODY2MjQyOH0.iVEqX-fwsl4scLLHNNFLh-m_QQhW-yhOIZ9Z-F_pac1Ohe8CUNSqcpyYOUK_qZ_HDc22W8YHacHcUk8RZqMpXA
{
"name": "Spring"
}
###
PUT {{baseUrl}}/api/skills/1
Content-Type: application/json
{
"name": "Java"
}
###
DELETE {{baseUrl}}/api/skills/11
\ No newline at end of file
package br.com.treinaweb.twjobs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
public class TwjobsApplication {
public static void main(String[] args) {
SpringApplication.run(TwjobsApplication.class, args);
}
}
package br.com.treinaweb.twjobs.api;
import br.com.treinaweb.twjobs.core.service.StatisticsService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RequiredArgsConstructor
@RestController
@RequestMapping("/statistics")
public class StatisticsRestController {
private final StatisticsService statisticsService;
@GetMapping("/all")
public ResponseEntity<Map<String, Object>> getAllStatistics() {
return ResponseEntity.ok(statisticsService.getStatistics());
}
}
package br.com.treinaweb.twjobs.api;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/users")
public class UsersRestController {
public final UserRepository userRepository;
// @GetMapping("statistics/count")
// @TWJobsPermissions.IsCompany
// public Long howMany() {
// return userRepository.countAllUsers();
// }
}
package br.com.treinaweb.twjobs.api.accepts.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.accepts.controllers.AcceptRestController;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class AcceptAssembler implements SimpleRepresentationModelAssembler<AcceptResponse> {
@Override
public void addLinks(EntityModel<AcceptResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(AcceptRestController.class).findById(id))
.withSelfRel()
.withType("GET");
Link updateLink = null;
try {
updateLink = linkTo(methodOn(AcceptRestController.class).update(null,id, null))
.withRel("update")
.withType("PUT");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
var deleteLink = linkTo(methodOn(AcceptRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(
selfLink,
updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<AcceptResponse>> resources) {
var selfLink = linkTo(methodOn(AcceptRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
Link createLink = null;
try {
createLink = linkTo(methodOn(AcceptRestController.class).create(null, null))
.withRel("create")
.withType("POST");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.accepts.controllers;
//import br.com.treinaweb.twjobs.api.ships.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.accepts.assemblers.AcceptAssembler;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptRequest;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.api.accepts.mappers.AcceptMapper;
import br.com.treinaweb.twjobs.api.file.FileManagerController;
import br.com.treinaweb.twjobs.core.enums.Role;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.exceptions.AcceptNotFoundException;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.AcceptCustomRepository;
import br.com.treinaweb.twjobs.core.repositories.AcceptRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.service.CadastroAcceptService;
import br.com.treinaweb.twjobs.core.service.EmailService;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
//"""
// Importante, quando eu tenho certeza que o dado existe, não usar findById: https://www.baeldung.com/spring-data-findbyid-vs-getbyid
// """
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/accepts")
public class AcceptRestController {
private final AcceptMapper acceptMapper;
private final AcceptAssembler acceptAssembler;
private final AcceptRepository acceptRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<AcceptResponse> pagedResourcesAssembler;
private final CadastroAcceptService cadastroAcceptService;
private final AcceptCustomRepository acceptCustomRepository;
private final VesselRepository vesselRepository;
private final FileManagerController fileManagerController;
@Autowired
private ObjectMapper mapper;
@GetMapping("statistics/count")
public Long howMany() {
return acceptRepository.countAllAccepts();
}
//"@PageableDefault(value = 7)" tamanho local para o tamanho da paginação. Deve ser igual ou menor ao valor encontrado no "application.properties"
@GetMapping
public CollectionModel<EntityModel<AcceptResponse>> findAll(@PageableDefault(value = 15) Pageable pageable) {
User user = securityService.getCurrentUser();
Long userId = user.getId();
// if (user.getRole().equals(Role.COMPANY)) {
// throw new NegocioException("É company");
var accepts = acceptRepository.findAll(pageable)
.map(acceptMapper::toAcceptResponse);
return pagedResourcesAssembler.toModel(accepts, acceptAssembler);
// } else if (user.getRole().equals(Role.CANDIDATE)) {
//// throw new NegocioException("É candidate");
// var accepts = acceptRepository.findAllByUserId(pageable,userId)
// .map(acceptMapper::toAcceptResponse);
// return pagedResourcesAssembler.toModel(accepts, acceptAssembler);
//
// }
// Page<AcceptResponse>
// accepts = acceptRepository.findAllByUserId(pageable,userId)
// .map(acceptMapper::toAcceptResponse);
//
//
// AJEITAR
// return null;
// return pagedResourcesAssembler.toModel(accepts, acceptAssembler);
}
@GetMapping("/custom")
public List<AcceptResponse> findTest(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "imo", required = false) String imo, @RequestParam(value = "status", required = false) String status, @RequestParam(value = "nome", required = false) String nome, @RequestParam(value = "categoria", required = false) String categoria, @RequestParam(value = "data_create", required = false) String data_create) {
List<AcceptResponse> accepts = acceptCustomRepository.acceptsCustom(id, imo, status, nome, categoria, data_create)
.stream()
.map(acceptMapper::toAcceptResponse)
.collect(Collectors.toList());
return accepts;
}
@GetMapping("/{id}")
public EntityModel<AcceptResponse> findById(@PathVariable Long id) {
User user = securityService.getCurrentUser();
Long userId = user.getId();
Accept accept;
if(user.getRole()==Role.COMPANY) {
accept = acceptRepository.findById(id)
.orElseThrow(AcceptNotFoundException::new);
} else {
accept = acceptRepository.findByIdAndUserId(id, userId)
.orElseThrow(AcceptNotFoundException::new);
}
var acceptResponse = acceptMapper.toAcceptResponse(accept);
return acceptAssembler.toModel(acceptResponse);
}
@PostMapping
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<AcceptResponse>
create(@Valid @RequestParam(name="acceptRequestForm", required=true) String acceptRequestForm, @RequestParam(name="foto", required=false) MultipartFile foto) throws JsonProcessingException {return cadastroAcceptService.salvar(acceptRequestForm, foto,"pauloacb2020@gmail.com");}
// renan.montenegro2018@gmail.com
@PutMapping("/{id}")
@TWJobsPermissions.IsCompany
public EntityModel<AcceptResponse> update(
// @RequestBody @Valid AcceptRequest acceptRequest,
// @PathVariable Long id
@Valid @RequestParam(name="acceptRequestForm", required=true) String acceptRequestForm, @PathVariable Long id, @RequestParam(name="foto", required=false) MultipartFile foto
) throws JsonProcessingException {
/*
Apenas admin podem setar manualmente o Status. O Candidate não pode.
Adicionar essa funcionalidade.
O mesmo para berços.
*/
//verifica extensao
String filename = foto.getOriginalFilename();
String extension = null;
int dotIndex = filename.lastIndexOf(".");
if (dotIndex >= 0) {
extension = filename.substring(dotIndex + 1);
}
String[] extensions = {"txt", "zip", "pdf"};
Boolean verifica = false;
if(extension!=null) {
for(String i : extensions){
if(i.equals(extension) ) {
verifica =true;
break;
}
}
if(!verifica){
throw new NegocioException(extension);
}
}
AcceptRequest acceptRequest = mapper.readValue(acceptRequestForm, AcceptRequest.class);
User user = securityService.getCurrentUser();
Long userId = user.getId();
Accept accept = new Accept();
// APENAS ADMIN PODEM ALTERAR OS DADOS DO ACEITE
// if(user.getRole()==Role.COMPANY) {
accept = acceptRepository.findById(id)
.orElseThrow(AcceptNotFoundException::new);
var acceptData = acceptMapper.toAccept(acceptRequest);
// acceptData.setId(id);
// if(user.getRole()!= Role.COMPANY &&(!Objects.equals(accept.getUser().getId(), userId))) {throw new NegocioException("Você não é proprietário.");}
// if(acceptData.getStatus() != null) {
//
// }
acceptData.setData_update(String.valueOf(LocalDate.now()));
acceptData.setTime_update(String.valueOf(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
var path = accept.getPath();
//se enviar arquivo, pega o nome dele
if(foto!=null) {
acceptData.setPath(foto.getOriginalFilename());
fileManagerController.uploadFile(foto);
//SE NÃO ENVIAR NENHUM ARQUIVO
} else {
accept.setPath(path);
}
//copia os campos que eu setar de uma accept para acceptData - ja preenche logo
BeanUtils.copyProperties(acceptData, accept, "id", "dataAccept", "data_create", "vessel", "user", "bercos");
// if(acceptData.getPath()==null) {
// accept.setPath(path);
// }
accept = acceptRepository.save(accept);
// } else {
// throw new NegocioException("Não tem permissão.");
// }
var acceptResponse = acceptMapper.toAcceptResponse(accept);
return acceptAssembler.toModel(acceptResponse);
}
@DeleteMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var accept = acceptRepository.findById(id)
.orElseThrow(AcceptNotFoundException::new);
User user = securityService.getCurrentUser();
Long userId = user.getId();
// ~~~ Se vc não é COMPANY nem dono dos dados
// if(user.getRole()!= Role.COMPANY &&(!Objects.equals(accept.getUser().getId(), userId))) {
// throw new NegocioException("Você não é proprietário.");
// }
acceptRepository.delete(accept);
return ResponseEntity.noContent().build();
}
}
// ~~~ DADOS FIXOS
// acceptCurrent.setData_create(accept.getData_create());
// acceptCurrent.setDataAccept(accept.getDataAccept());
// acceptCurrent.setUser(accept.getUser());
// acceptCurrent.setVessel(accept.getVessel());
//// ~~~ DADOS MUTÁVEIS
// if(acceptCurrent.getStatus()==accept.getStatus()) {
// acceptCurrent.setStatus(accept.getStatus())
// ;
// }
//// else if(acceptCurrent.getStatus()==Role.)
//
// else if(user.getRole()!= Role.COMPANY){throw new NegocioException("Você não tem permissão para alterar o status do aceite.");}
// if(Objects.equals(accept.getObs(), acceptCurrent.getObs())) {acceptCurrent.setObs(accept.getObs());}
// if(Objects.equals(accept.getImo(), acceptCurrent.getImo())) {acceptCurrent.setImo(accept.getImo());}
// if((user.getRole()==Role.COMPANY) && (acceptCurrent.getBercos()==accept.getBercos())) {acceptCurrent.setBercos(accept.getBercos());}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.accepts.dtos;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AcceptRequest {
// NOT EMPTY SÒ COM STRING
// COM NUMEROS È O NOTNULL
// AJEITAR
// @VesselImoIsUnique
@NotNull(message = "IMO não pode ser nulo")
// @Size(min = 7, message = "IMO deve ter no mínimo 7 caracteres")
private Long imo;
//CAN BE NULL
private String obs;
private String status;
private String restricoes;
//CAN BE NULL
private List<Berco> bercos;
// ~~~ PODE SER NULO
private List<Long> bercosId;
// @NotEmpty(message = "data não deve estar vazia")
// private String dataAccept;
// @NotEmpty(message = "data não deve estar vazia")
// private String data_create;
// @NotEmpty(message = "data não deve estar vazia")
// private String data_update;
// Dados navio
private String mmsi;
private String nome;
@NotNull(message = "LOA deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float loa;
private Float boca;
@NotNull(message = "DWT deve ser maior que zero")
// @Size(value=1 , message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
@NotEmpty
@Size(min = 1, max = 100, message = "CATEGORIA deve ter no mínimo 1 e no máximo 100 caracteres")
private String categoria;
private Integer flag;
@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_entrada;
@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_saida;
}
package br.com.treinaweb.twjobs.api.accepts.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import br.com.treinaweb.twjobs.core.enums.CategoriaVessel;
import br.com.treinaweb.twjobs.core.models.Berco;
import lombok.*;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class AcceptResponse {
private Long id;
private String user;
private String vessel;
private Long imo;
private String status;
private String obs;
private String restricoes;
private String dataAccept;
private String data_create;
private String data_update;
private String time_accept;
private String time_create;
private String time_update;
private List<Berco> bercos;
private String path;
// Dados navio
private String mmsi;
private String nome;
private Float loa;
private Float boca;
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
private String categoria;
private Integer flag;
private Float calado_entrada;
private Float calado_saida;
// private List<Long> bercos;
//private List<BercoRequestAceite> bercos;
}
package br.com.treinaweb.twjobs.api.accepts.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptRequest;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Aceite;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
public interface AcceptMapper {
//
Accept toAccept(AcceptRequest acceptRequest);
AcceptResponse toAcceptResponse(Accept accept);
//
}
package br.com.treinaweb.twjobs.api.accepts.mappers;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptRequest;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Aceite;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperAcceptMapper implements AcceptMapper {
private final ModelMapper modelMapper;
@Override
public AcceptResponse toAcceptResponse(Accept accept) {
return modelMapper.map(accept, AcceptResponse.class);
}
@Override
public Accept toAccept(@Valid AcceptRequest acceptRequest) {
return modelMapper.map(acceptRequest, Accept.class);
}
}
package br.com.treinaweb.twjobs.api.aceites.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.aceites.controllers.AceiteRestController;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class AceiteAssembler implements SimpleRepresentationModelAssembler<AceiteResponse> {
@Override
public void addLinks(EntityModel<AceiteResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(AceiteRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(AceiteRestController.class).update(null, id))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(AceiteRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(selfLink, updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<AceiteResponse>> resources) {
var selfLink = linkTo(methodOn(AceiteRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(AceiteRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.aceites.controllers;
//import br.com.treinaweb.twjobs.api.ships.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.aceites.assemblers.AceiteAssembler;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteRequest;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import br.com.treinaweb.twjobs.api.aceites.mappers.AceiteMapper;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.core.exceptions.AceiteNotFoundException;
import br.com.treinaweb.twjobs.core.models.Aceite;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.AceiteRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/aceites")
public class AceiteRestController {
private final AceiteMapper aceiteMapper;
private final AceiteAssembler aceiteAssembler;
private final AceiteRepository aceiteRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<AceiteResponse> pagedResourcesAssembler;
private final VesselRepository vesselRepository;
@GetMapping
public CollectionModel<EntityModel<AceiteResponse>> findAll(Pageable pageable) {
var aceites = aceiteRepository.findAll(pageable)
.map(aceiteMapper::toAceiteResponse);
return pagedResourcesAssembler.toModel(aceites, aceiteAssembler);
}
@GetMapping("/{id}")
public EntityModel<AceiteResponse> findById(@PathVariable Long id) {
var aceite = aceiteRepository.findById(id)
.orElseThrow(AceiteNotFoundException::new);
var aceiteResponse = aceiteMapper.toAceiteResponse(aceite);
return aceiteAssembler.toModel(aceiteResponse);
}
private final ModelMapper modelMapper;
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<AceiteResponse> create(@RequestBody @Valid AceiteRequest aceiteRequest) {
var aceite = aceiteMapper.toAceite(aceiteRequest);
aceite.setUser(securityService.getCurrentUser());
var navio = vesselRepository.findByImo(aceite.getImo());
// aceite.setImo((long) 9470820);
// var navio = vesselRepository.existsByImo(aceite.getImo());
//var navio="Peróla Brazil";
// aceite.setVessel(modelMapper.map(navio, Vessel.class));
Vessel existingCustomer = navio.get();
//String nameWeWanted = existingCustomer.getName();
aceite.setVessel(existingCustomer);
aceite = aceiteRepository.save(aceite);
var aceiteResponse = aceiteMapper.toAceiteResponse(aceite);
return aceiteAssembler.toModel(aceiteResponse);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsOwner
public EntityModel<AceiteResponse> update(
@RequestBody @Valid AceiteRequest aceiteRequest,
@PathVariable Long id
) {
var aceite = aceiteRepository.findById(id)
.orElseThrow(AceiteNotFoundException::new);
var aceiteData = aceiteMapper.toAceite(aceiteRequest);
BeanUtils.copyProperties(aceiteData, aceite, "id", "company", "candidates");
aceite = aceiteRepository.save(aceite);
var aceiteResponse = aceiteMapper.toAceiteResponse(aceite);
return aceiteAssembler.toModel(aceiteResponse);
}
@DeleteMapping("/{id}")
@TWJobsPermissions.IsOwner
public ResponseEntity<?> delete(@PathVariable Long id) {
var aceite = aceiteRepository.findById(id)
.orElseThrow(AceiteNotFoundException::new);
aceiteRepository.delete(aceite);
return ResponseEntity.noContent().build();
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.aceites.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AceiteRequest {
private Long user;
private Long vessel;
// @NotEmpty
private Long imo;
// @NotEmpty
private AceiteStatus status;
}
package br.com.treinaweb.twjobs.api.aceites.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class AceiteResponse {
private Long id;
private String user;
private String vessel;
private Long imo;
private AceiteStatus status;
}
package br.com.treinaweb.twjobs.api.aceites.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteRequest;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.core.models.Aceite;
import jakarta.validation.Valid;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
public interface AceiteMapper {
//
AceiteResponse toAceiteResponse(Aceite aceite);
Aceite toAceite(AceiteRequest aceiteRequest);
//
}
package br.com.treinaweb.twjobs.api.aceites.mappers;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteRequest;
import br.com.treinaweb.twjobs.api.aceites.dtos.AceiteResponse;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.core.models.Aceite;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperAceiteMapper implements AceiteMapper {
private final ModelMapper modelMapper;
@Override
public AceiteResponse toAceiteResponse(Aceite aceite) {
return modelMapper.map(aceite, AceiteResponse.class);
}
@Override
public Aceite toAceite(@Valid AceiteRequest aceiteRequest) {
return modelMapper.map(aceiteRequest, Aceite.class);
}
}
package br.com.treinaweb.twjobs.api.auth.controllers;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.crypto.password.PasswordEncoder;
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;
import br.com.treinaweb.twjobs.api.auth.dtos.LoginRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.RefreshRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.TokenResponse;
import br.com.treinaweb.twjobs.api.auth.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.UserResponse;
import br.com.treinaweb.twjobs.api.auth.mappers.UserMapper;
import br.com.treinaweb.twjobs.core.repositories.UserRepository;
import br.com.treinaweb.twjobs.core.services.jwt.JwtService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/auth")
public class AuthRestController {
private final UserMapper userMapper;
private final JwtService jwtService;
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final AuthenticationManager authenticationManager;
@PostMapping("/register")
@ResponseStatus(code = HttpStatus.CREATED)
public UserResponse register(@RequestBody @Valid UserRequest userRequest) {
var user = userMapper.toUser(userRequest);
var passwordHash = passwordEncoder.encode(user.getPassword());
user.setPassword(passwordHash);
user = userRepository.save(user);
return userMapper.toUserResponse(user);
}
@PostMapping("/login")
public TokenResponse login(@RequestBody @Valid LoginRequest loginRequest) {
var user = userRepository.findByEmail(loginRequest.getEmail());
var usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
loginRequest.getEmail(),
loginRequest.getPassword()
);
authenticationManager.authenticate(usernamePasswordAuthenticationToken);
return TokenResponse.builder()
.accessToken(jwtService.generateAccessToken(loginRequest.getEmail(), user.get().getRole()))
.refreshToken(jwtService.generateRefreshToken(loginRequest.getEmail(), user.get().getRole()))
.build();
}
@PostMapping("/refresh")
public TokenResponse refresh(@RequestBody @Valid RefreshRequest refreshRequest) {
var sub = jwtService.getSubFromRefreshToken(refreshRequest.getRefreshToken());
var user = userRepository.findByEmail(sub);
return TokenResponse.builder()
.accessToken(jwtService.generateAccessToken(sub, user.get().getRole()))
.refreshToken(jwtService.generateRefreshToken(sub, user.get().getRole()))
.build();
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.auth.cors;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("GET", "POST", "DELETE", "PUT");
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.auth.dtos;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LoginRequest {
@Email
@NotEmpty
private String email;
@NotEmpty
private String password;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RefreshRequest {
@NotEmpty
private String refreshToken;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TokenResponse {
private String accessToken;
private String refreshToken;
// private String roleReturn;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserRequest {
@NotEmpty
private String name;
@Email
@NotEmpty
private String email;
@NotEmpty
private String password;
@NotNull
private Role role;
}
package br.com.treinaweb.twjobs.api.auth.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private Long id;
private String name;
private String email;
private Role role;
}
package br.com.treinaweb.twjobs.api.auth.mappers;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.auth.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class ModelMapperUserMapper implements UserMapper {
private final ModelMapper modelMapper;
@Override
public UserResponse toUserResponse(User user) {
return modelMapper.map(user, UserResponse.class);
}
@Override
public User toUser(UserRequest userRequest) {
return modelMapper.map(userRequest, User.class);
}
}
package br.com.treinaweb.twjobs.api.auth.mappers;
import br.com.treinaweb.twjobs.api.auth.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.auth.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
public interface UserMapper {
UserResponse toUserResponse(User user);
User toUser(UserRequest userRequest);
}
package br.com.treinaweb.twjobs.api.bercos.assemblers;
import br.com.treinaweb.twjobs.api.bercos.controllers.BercosRestController;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class BercosAssembler implements SimpleRepresentationModelAssembler<BercoResponse> {
@Override
public void addLinks(EntityModel<BercoResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(BercosRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(BercosRestController.class).update(null, id))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(BercosRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(selfLink, updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<BercoResponse>> resources) {
var selfLink = linkTo(methodOn(BercosRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(BercosRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.bercos.controllers;
import br.com.treinaweb.twjobs.api.bercos.assemblers.BercosAssembler;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoRequest;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import br.com.treinaweb.twjobs.api.bercos.mappers.BercoMapper;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.exceptions.AceiteNotFoundException;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.exceptions.BercoNotFoundException;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.BercoCustomRepository;
import br.com.treinaweb.twjobs.core.repositories.BercoRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.services.CadastroVesselService;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
//@CrossOrigin
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/bercos")
public class BercosRestController {
private final BercosAssembler bercoAssembler;
private final BercoMapper bercoMapper;
private final CadastroVesselService cadastroVesselService;
private final BercoRepository bercoRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<BercoResponse> pagedResourcesAssembler;
private final VesselRepository vesselRepository;
private final BercoCustomRepository bercoCustomRepository;
@GetMapping
public CollectionModel<EntityModel<BercoResponse>> findAll(Pageable pageable) {
var bercos = bercoRepository.findAll(pageable)
.map(bercoMapper::toBercoResponse);
return pagedResourcesAssembler.toModel(bercos, bercoAssembler);
}
@GetMapping("/{id}")
public EntityModel<BercoResponse> findById(@PathVariable Long id) {
var berco = bercoRepository.findById(id)
.orElseThrow(BercoNotFoundException::new);
var bercoResponse = bercoMapper.toBercoResponse(berco);
return bercoAssembler.toModel(bercoResponse);
}
@GetMapping("/custom")
public List<BercoResponse> custom(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "categoria", required = false) String categoria, @RequestParam(value = "nome", required = false) String nome){
List<BercoResponse> bercos = bercoCustomRepository.bercosCustom(id, categoria, nome)
.stream()
.map(bercoMapper::toBercoResponse)
.toList();
return bercos;
}
// @GetMapping("statistics/count")
// @TWJobsPermissions.IsCompany
// public Long howManyAccepts() {
// return bercoRepository.countAllBercos();
// }
@ResponseStatus(HttpStatus.CREATED)
@TWJobsPermissions.IsCompany
@PostMapping
public EntityModel<BercoResponse> create(@Valid @RequestBody BercoRequest bercoRequest) {
var berco = bercoMapper.toBerco(bercoRequest);
berco = bercoRepository.save(berco);
List<Vessel> navios = vesselRepository.findAll();
for(Vessel i : navios){
i.setSt_ver_vessel(VeriStatus.valueOf("N"));
}
var bercoResponse = bercoMapper.toBercoResponse(berco);
return bercoAssembler.toModel(bercoResponse);
}
@PutMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public EntityModel<BercoResponse> update(
@RequestBody @Valid BercoRequest bercoRequest,
@PathVariable Long id
) {
var berco = bercoRepository.findById(id)
.orElseThrow(BercoNotFoundException::new);
var bercoData = bercoMapper.toBerco(bercoRequest);
BeanUtils.copyProperties(bercoData, berco, "id", "company", "candidates");
berco = bercoRepository.save(berco);
List<Vessel> navios = vesselRepository.findAll();
for(Vessel i : navios){
i.setSt_ver_vessel(VeriStatus.valueOf("N"));
}
var bercoResponse = bercoMapper.toBercoResponse(berco);
return bercoAssembler.toModel(bercoResponse);
}
@DeleteMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var berco = bercoRepository.findById(id)
.orElseThrow(BercoNotFoundException::new);
bercoRepository.delete(berco);
List<Vessel> navios = vesselRepository.findAll();
for(Vessel i : navios){
i.setSt_ver_vessel(VeriStatus.valueOf("N"));
}
return ResponseEntity.noContent().build();
}
// Continuar colocando os métodos e substituindo por vessels.
// Depois corrigir os objetos que talvez ainda não existam
// Testar o cadastro de um vessel pra ver se guarda o user_id
}
package br.com.treinaweb.twjobs.api.bercos.dtos;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BercoRequest {
// AJEITAR
// private Long user;
//not empty não está funcionando. Ajeiter.
// @NotEmpty
private String nome;
private Long compri_estrutural;
private Long compri_util;
private Float dwt;
private Long largura;
private Long profundidade;
private Float calado_max;
private Float boca_max;
private Float loa_max;
private String categoria;
// private List<Long> accepts; //Novo request que não possua essa linha.
private List<Accept> accepts;
}
package br.com.treinaweb.twjobs.api.bercos.dtos;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Berco;
import lombok.*;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class BercoResponse {
private Long id;
private String nome;
private Long compri_estrutural;
private Long compri_util;
private Float dwt;
private Long largura;
private Long profundidade;
private Float calado_max;
private Float boca_max;
private Float loa_max;
private String categoria;
private List<String> accepts;
}
package br.com.treinaweb.twjobs.api.bercos.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoRequest;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.models.Vessel;
public interface BercoMapper {
Berco toBerco(BercoRequest bercoRequest);
BercoResponse toBercoResponse(Berco berco);
}
package br.com.treinaweb.twjobs.api.bercos.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoRequest;
import br.com.treinaweb.twjobs.api.bercos.dtos.BercoResponse;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.models.Vessel;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperBercoMapper implements BercoMapper {
private final ModelMapper modelMapper;
@Override
public Berco toBerco(BercoRequest bercoRequest) {
return modelMapper.map(bercoRequest, Berco.class);
}
@Override
public BercoResponse toBercoResponse(Berco berco) {
return modelMapper.map(berco, BercoResponse.class);
}
}
package br.com.treinaweb.twjobs.api.blackList.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.blackList.controllers.BlackListRestController;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class BlackListAssembler implements SimpleRepresentationModelAssembler<BlackListResponse> {
@Override
public void addLinks(EntityModel<BlackListResponse> resource) {
var id = resource.getContent().getId();
// var selfLink = linkTo(methodOn(AcceptRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
// var updateLink = linkTo(methodOn(BlackListRestController.class).update(null, id))
// .withRel("update")
// .withType("PUT");
//
// var deleteLink = linkTo(methodOn(BlackListRestController.class).delete(id))
// .withRel("delete")
// .withType("DELETE");
resource.add(
// selfLink,
// updateLink
// ,
// deleteLink
);
}
@Override
public void addLinks(CollectionModel<EntityModel<BlackListResponse>> resources) {
var selfLink = linkTo(methodOn(BlackListRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(BlackListRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.blackList.controllers;
//import br.com.treinaweb.twjobs.api.ships.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.blackList.assemblers.BlackListAssembler;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListRequest;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import br.com.treinaweb.twjobs.api.blackList.mappers.BlackListMapper;
import br.com.treinaweb.twjobs.core.enums.Role;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.exceptions.AcceptNotFoundException;
import br.com.treinaweb.twjobs.core.exceptions.BlackListedNotFoundException;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.BlackList;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.AcceptRepository;
import br.com.treinaweb.twjobs.core.repositories.BlackListCustomRepository;
import br.com.treinaweb.twjobs.core.repositories.BlackListRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.service.CadastroAcceptService;
import br.com.treinaweb.twjobs.core.service.EmailService;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
//"""
// Importante, quando eu tenho certeza que o dado existe, não usar findById: https://www.baeldung.com/spring-data-findbyid-vs-getbyid
// """
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/black-list")
public class BlackListRestController {
private final BlackListMapper blackListMapper;
private final BlackListAssembler blackListAssembler;
private final BlackListRepository blackListRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<BlackListResponse> pagedResourcesAssembler;
private final CadastroAcceptService cadastroAcceptService;
private final BlackListCustomRepository blackListCustomRepository;
private final VesselRepository vesselRepository;
//"@PageableDefault(value = 7)" tamanho local para o tamanho da paginação. Deve ser igual ou menor ao valor encontrado no "application.properties"
@GetMapping
@TWJobsPermissions.IsCompany
public CollectionModel<EntityModel<BlackListResponse>> findAll(@PageableDefault(value = 15) Pageable pageable) {
User user = securityService.getCurrentUser();
Long userId = user.getId();
// org.springframework.data.domain.Page<BlackListResponse> blackLists = null;
// if (user.getRole().equals(Role.COMPANY)) {
// throw new NegocioException("É company");
var blackLists = blackListRepository.findAll(pageable)
.map(blackListMapper::toBlackListResponse);
return pagedResourcesAssembler.toModel(blackLists, blackListAssembler);
// } else if (user.getRole().equals(Role.CANDIDATE)) {
//// throw new NegocioException("É candidate");
//
// blackLists = blackListRepository.findAllByUserId(pageable, userId)
// .map(blackListMapper::toBlackListResponse);
// pagedResourcesAssembler.toModel(blackLists, blackListAssembler);
//
// }
// Page<AcceptResponse>
// accepts = acceptRepository.findAllByUserId(pageable,userId)
// .map(acceptMapper::toAcceptResponse);
//
//
// return null;
// return pagedResourcesAssembler.toModel(blackLists, blackListAssembler);
}
@GetMapping("/statistics/count")
@TWJobsPermissions.IsCompany
public Long howMany() {
return blackListRepository.countAllBlackLists();
}
@GetMapping("/custom")
@TWJobsPermissions.IsCompany
public List<BlackListResponse> findTest(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "imo", required = false) String imo, @RequestParam(value = "data_create", required = false) String data_create, @RequestParam(value = "time_create", required = false) String time_create) {
List<BlackListResponse> blackListeds = blackListCustomRepository.blackListedsCustom(id, imo, data_create, time_create)
.stream()
.map(blackListMapper::toBlackListResponse)
.toList();
return blackListeds;
}
@Autowired
private EmailService emailService;
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<BlackListResponse> create(@RequestBody @Valid BlackListRequest blackListRequest) {
var blackList = blackListMapper.toBlackList(blackListRequest);
var vessel = vesselRepository.findByImo(blackList.getImo());
// """Setando as datas de alteração"""
blackList.setData_blacklisted(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setData_create(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setData_update(String.valueOf(LocalDate.now()));
blackList.setTime_blacklisted(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setTime_create(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
blackList.setTime_update(String.valueOf(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
// blackList.setMmsi(vessel.get().getMmsi());
// blackList.setNome(vessel.get().getNome());
// blackList.setLoa(vessel.get().getLoa());
// blackList.setBoca(vessel.get().getBoca());
// blackList.setDwt(vessel.get().getDwt());
// blackList.setPontal(vessel.get().getPontal());
// blackList.setPonte_mfold(vessel.get().getPonte_mfold());
// blackList.setMfold_quilha(vessel.get().getMfold_quilha());
// if(vessel.get().getCategoria() != null) {
// blackList.setCategoria(vessel.get().getCategoria());
// } else {
// blackList.setCategoria("nao informado");
// }
//
// blackList.setFlag(Integer.valueOf(vessel.get().getFlag()));
// blackList.setCalado_entrada(vessel.get().getCalado_entrada());
// blackList.setCalado_saida(vessel.get().getCalado_saida());
blackList = blackListRepository.save(blackList);
var vesselResponse = blackListMapper.toBlackListResponse(blackList);
return blackListAssembler.toModel(vesselResponse);
}
@PutMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public EntityModel<BlackListResponse> update(
@RequestBody @Valid BlackListRequest blackListRequest,
@PathVariable Long id
) {
var blackList = blackListRepository.findById(id)
.orElseThrow(BlackListedNotFoundException::new);
var BlackListData = blackListMapper.toBlackList(blackListRequest);
BlackListData.setData_update(String.valueOf(LocalDate.now()));
BlackListData.setTime_update(String.valueOf(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
BeanUtils.copyProperties(BlackListData, blackList, "id", "imo", "data_blacklisted","data_create","time_blacklisted","time_create");
blackList = blackListRepository.save(blackList);
var acceptResponse = blackListMapper.toBlackListResponse(blackList);
return blackListAssembler.toModel(acceptResponse);
}
//
// @TWJobsPermissions.IsOwner
@DeleteMapping("/{id}")
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var blackList = blackListRepository.findById(id)
.orElseThrow(BlackListedNotFoundException::new);
/*check_user(accept);*/
blackListRepository.delete(blackList);
return ResponseEntity.noContent().build();
}
//
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.blackList.dtos;
import br.com.treinaweb.twjobs.core.models.Berco;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BlackListRequest {
// AJEITAR
// @VesselImoIsUnique
@NotNull(message = "IMO deve ter no mínimo 7 caracteres")
// @Size(min = 7, message = "IMO deve ter no mínimo 7 caracteres")
private Long imo;
@NotEmpty(message = "MOTIVO não deve estar vazio.")
private String reason;
// private String data_blacklisted;
// private String data_create;
// private String data_update;
//
// private String time_blacklisted;
// private String time_create;
// private String time_update;
// Dados navio
private String mmsi="Null";
private String nome="Null";
// @NotNull(message = "LOA deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float loa=0.0F;
private Float boca=0.0F;
// @NotNull(message = "DWT deve ser maior que zero")
// @Size(value=1 , message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float dwt=0.0F;
private Float pontal=0.0F;
private Float ponte_mfold=0.0F;
private Float mfold_quilha=0.0F;
// @NotEmpty
// @Size(min = 1, max = 100, message = "CATEGORIA deve ter no mínimo 1 e no máximo 100 caracteres")
private String categoria="Null";
private Integer flag=0;
//@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_entrada=0.0F;
//@NotNull(message = "calado deve ser maior que zero")
// @Size(min = 1, max = 10, message = "Calado deve ter no mínimo 1 e no máximo 10 caracteres")
private Float calado_saida=0.0F;
}
package br.com.treinaweb.twjobs.api.blackList.dtos;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import lombok.*;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class BlackListResponse {
private Long id;
private Long imo;
private String reason;
private String data_blacklisted;
private String data_create;
private String data_update;
private String time_blacklisted;
private String time_create;
private String time_update;
// private List<Long> bercos;
//private List<BercoRequestAceite> bercos;
// Dados navio
private String mmsi;
private String nome;
private Float loa;
private Float boca;
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
private String categoria;
private Integer flag;
private Float calado_entrada;
private Float calado_saida;
}
package br.com.treinaweb.twjobs.api.blackList.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListRequest;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.BlackList;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
public interface BlackListMapper {
//
BlackList toBlackList(BlackListRequest blackListRequest);
BlackListResponse toBlackListResponse(BlackList blackList);
//
}
package br.com.treinaweb.twjobs.api.blackList.mappers;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListRequest;
import br.com.treinaweb.twjobs.api.blackList.dtos.BlackListResponse;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.BlackList;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperBlackListMapper implements BlackListMapper {
private final ModelMapper modelMapper;
@Override
public BlackListResponse toBlackListResponse(BlackList blackList) {
return modelMapper.map(blackList, BlackListResponse.class);
}
@Override
public BlackList toBlackList(@Valid BlackListRequest blackListRequest) {
return modelMapper.map(blackListRequest, BlackList.class);
}
}
package br.com.treinaweb.twjobs.api.common.dtos;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResponse {
private String message;
@Builder.Default
private LocalDateTime timestamp = LocalDateTime.now();
}
package br.com.treinaweb.twjobs.api.common.dtos;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ValidationErrorResponse {
private String message;
@Builder.Default
private LocalDateTime timestamp = LocalDateTime.now();
private Map<String, List<String>> errors;
}
package br.com.treinaweb.twjobs.api.common.filters;
import java.io.IOException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import br.com.treinaweb.twjobs.core.exceptions.JwtServiceException;
import br.com.treinaweb.twjobs.core.services.jwt.JwtService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class AccessTokenRequestFilter extends OncePerRequestFilter {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String TOKEN_PREFIX = "Bearer ";
private final JwtService jwtService;
private final UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException {
try {
var token = "";
var email = "";
var header = request.getHeader(AUTHORIZATION_HEADER);
if (isTokenPresent(header)) {
token = header.substring(TOKEN_PREFIX.length());
email = jwtService.getSubFromAccessToken(token);
}
if (isEmailValid(email)) {
setAuthentication(request, email);
}
filterChain.doFilter(request, response);
} catch (JwtServiceException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getLocalizedMessage());
}
}
private void setAuthentication(HttpServletRequest request, String email) {
var userDetails = userDetailsService.loadUserByUsername(email);
var authentication = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
private boolean isEmailValid(String email) {
return email != null && !email.isEmpty();
}
private boolean isTokenPresent(String header) {
return header != null && header.startsWith(TOKEN_PREFIX);
}
}
package br.com.treinaweb.twjobs.api.common.handlers;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import br.com.treinaweb.twjobs.api.common.dtos.ErrorResponse;
import br.com.treinaweb.twjobs.api.common.dtos.ValidationErrorResponse;
import br.com.treinaweb.twjobs.core.exceptions.JwtServiceException;
import br.com.treinaweb.twjobs.core.exceptions.ModelNotFoundException;
@RestControllerAdvice
public class ApiExceptionHandler {
@ExceptionHandler(ModelNotFoundException.class)
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public ErrorResponse handleModelNotFoundException(
ModelNotFoundException exception
) {
return ErrorResponse.builder()
.message(exception.getLocalizedMessage())
.build();
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public ValidationErrorResponse handleMethodArgumentNotValidException(
MethodArgumentNotValidException exception
) {
var errors = exception.getBindingResult().getFieldErrors()
.stream()
.collect(Collectors.groupingBy(
fieldError -> fieldError.getField(),
Collectors.mapping(
fieldError -> fieldError.getDefaultMessage(),
Collectors.toList()
)
));
return ValidationErrorResponse.builder()
.message("Validation error")
.errors(errors)
.build();
}
@ExceptionHandler(JwtServiceException.class)
@ResponseStatus(code = HttpStatus.UNAUTHORIZED)
public ErrorResponse handleJwtServiceException(JwtServiceException e) {
return ErrorResponse.builder()
.message(e.getLocalizedMessage())
.build();
}
}
package br.com.treinaweb.twjobs.api.common.handlers;
import java.io.IOException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
public class TokenAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(
HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException
) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getLocalizedMessage());
}
}
package br.com.treinaweb.twjobs.api.common.handlers;
import java.io.IOException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
public class TokenAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException
) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getLocalizedMessage());
}
}
package br.com.treinaweb.twjobs.api.emailSend;
import br.com.treinaweb.twjobs.core.enums.EmailActivation;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.models.EmailSend;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.EmailSendRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/emailSend")
public class EmailSendRestController {
private final EmailSendRepository emailSendRepository;
private final SecurityService securityService;
// COLOCAR DEPOIS COMO DEFAULT - STATUS = DISABLE
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EmailSend add(@RequestBody EmailSend emailSend) {
emailSend.setUser(securityService.getCurrentUser());
return emailSendRepository.save(emailSend);
}
@GetMapping
@TWJobsPermissions.IsCompany
public List<EmailSend> getAll() {
return emailSendRepository.findAllByUserId(securityService.getCurrentUser().getId());
}
@PutMapping("/{id}")
@TWJobsPermissions.IsCompany
public EmailSend put(@PathVariable Long id,@RequestBody EmailSend emailSend) {
// Se liga que no frontend, assim que o usuário clicar a requisição vai ser feita mediante
// clique na check-box
// Se for enable : checa se todos os outros estão disable
// se estão: salva
// se não, retorna um erro
emailSend.setId(id);
emailSend.setUser(securityService.getCurrentUser());
Boolean check = emailSendRepository.existsByUserIdAndStatus(securityService.getCurrentUser().getId(), emailSend.getStatus());
if(emailSend.getStatus() == EmailActivation.enable) {
if(check) {
emailSend.setStatus(EmailActivation.disable);
throw new NegocioException("Você só pode ter 1 e-mail ativo");
}
}
return emailSendRepository.save(emailSend);
}
@DeleteMapping("{id}")
@TWJobsPermissions
public ResponseEntity<Void> delete(@PathVariable Long id) {
Boolean check = emailSendRepository.existsByUserIdAndId(securityService.getCurrentUser().getId(), id);
if(check) {
// return null;
emailSendRepository.deleteById(id);
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}
}
package br.com.treinaweb.twjobs.api.exceptionhandler;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import lombok.AllArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.*;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.net.URI;
import java.util.stream.Collectors;
@AllArgsConstructor
@RestControllerAdvice
public class ApiExceptionHanler extends ResponseEntityExceptionHandler {
private final MessageSource messageSource;
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {
ProblemDetail problemDetail = ProblemDetail.forStatus(status);
problemDetail.setTitle("Um ou mais campos estão inválidos");
problemDetail.setType(URI.create("https://..."));
var fields = ex.getBindingResult().getAllErrors().stream().collect(Collectors.toMap(error -> ((FieldError) error).getField(),
error -> messageSource.getMessage(error, LocaleContextHolder.getLocale())));
problemDetail.setProperty("fields", fields);
return super.handleExceptionInternal(ex, problemDetail, headers, status, request);
}
@ExceptionHandler(NegocioException.class)
public ProblemDetail handleNegocio(NegocioException e){
ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
problemDetail.setTitle(e.getMessage());
problemDetail.setType(URI.create("https://..."));
return problemDetail;
}
@ExceptionHandler(DataIntegrityViolationException.class)
public ProblemDetail handleDataIntegrityViolation(DataIntegrityViolationException e){
ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.CONFLICT);
problemDetail.setTitle("Recurso está em uso");
problemDetail.setType(URI.create("https://..."));
return problemDetail;
}
}
package br.com.treinaweb.twjobs.api.file;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Files;
import java.util.logging.Level;
import java.util.logging.Logger;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class FileManagerController {
@Autowired
private FileStorageService fileStorageService;
private static final Logger log = Logger.getLogger(FileManagerController.class.getName());
// @PostMapping("/upload-file")
public boolean uploadFile(
// @RequestParam("file")
MultipartFile file) {
try {
fileStorageService.saveFile(file);
return true;
} catch(Exception e) {
log.log(Level.SEVERE, "Exception in file upload.", e);
}
return false;
}
@GetMapping("/download-file")
public ResponseEntity<Resource> downloadFile(
@RequestParam("filename")
String filename) {
log.log(Level.INFO, "[REGULAR] with /download-file");
try{
var fileToDownload = fileStorageService.getDownloadFile(filename);
return ResponseEntity.ok()
.contentLength(fileToDownload.length())
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; fileName =\"" + filename + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new InputStreamResource(Files.newInputStream(fileToDownload.toPath())));
} catch(Exception e) {
return ResponseEntity.notFound().build();
}
// """ PERMITIR QUE SEJA UMA URL NORMAL PARA QUE CONFORME O USUÁRIO CLIQUE AQUELE ARQUIVO ESPECIFICO SEJA BAIXADO
// """ E não uma requisição baixe arquivo por arquivo.
// """ Enviar email pro user. (I)Para accept / (II)Para cadastro de usuário.
// (I)https://youtu.be/_MwdIaMy_Ao?si=V-xn0Rb8nkUow97j (II)https://youtu.be/V-ABkNuubaI?si=83K-Ejfjxs7Gy3if
}
// ~~ DIVIDE FILE EM PARTES -> BAIXA PARALELO
@GetMapping("/download-faster")
public ResponseEntity<Resource> downloadFileFaster(
@RequestParam("fileName")
String filename) {
log.log(Level.INFO, "[FASTER] with /download-faster");
try{
var fileToDownload = fileStorageService.getDownloadFile(filename);
return ResponseEntity.ok()
.contentLength(fileToDownload.length())
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; fileName =\"" + filename + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new FileSystemResource(fileToDownload));
} catch(Exception e) {
return ResponseEntity.notFound().build();
}
// """ PERMITIR QUE SEJA UMA URL NORMAL PARA QUE CONFORME O USUÁRIO CLIQUE AQUELE ARQUIVO ESPECIFICO SEJA BAIXADO
// """ E não uma requisição baixe arquivo por arquivo.
// """ Enviar email pro user. (I)Para accept / (II)Para cadastro de usuário.
// (I)https://youtu.be/_MwdIaMy_Ao?si=V-xn0Rb8nkUow97j (II)https://youtu.be/V-ABkNuubaI?si=83K-Ejfjxs7Gy3if
}
}
package br.com.treinaweb.twjobs.api.file;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Objects;
@Service
public class FileStorageService {
private static final String STORAGE_DIRECTORY = "C:\\StorageJava";
public void saveFile(MultipartFile fileToSave) throws IOException {
if(fileToSave == null) {
throw new NullPointerException("The file is null");
}
var targetFile = new File(STORAGE_DIRECTORY + File.separator + fileToSave.getOriginalFilename());
if(!Objects.equals(targetFile.getParent(), STORAGE_DIRECTORY)){
throw new SecurityException("Unsupported file name.");
}
// O getInputStream é o que salva o file
Files.copy(fileToSave.getInputStream(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
public File getDownloadFile(String fileName) throws Exception{
if(fileName == null){
throw new NullPointerException("FileName is null");
}
var fileToDownload = new File(STORAGE_DIRECTORY + File.separator + fileName);
if(!Objects.equals(fileToDownload.getParent(), STORAGE_DIRECTORY)) {
throw new SecurityException("Unsupported fileName!");
}
if(!fileToDownload.exists()) {
throw new FileNotFoundException("No file named:" + fileName);
}
return fileToDownload;
}
}
//package br.com.treinaweb.twjobs.api.files;
//
//import lombok.RequiredArgsConstructor;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.core.io.FileSystemResource;
//import org.springframework.core.io.InputStreamResource;
//import org.springframework.core.io.Resource;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.MediaType;
//import org.springframework.http.ResponseEntity;
//import org.springframework.ui.Model;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.File;
//import java.io.IOException;
//import java.nio.file.DirectoryStream;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.util.logging.Level;
//import java.util.logging.Logger;
//import java.util.stream.Collectors;
//import java.util.stream.StreamSupport;
//
//@RestController
////@RequiredArgsConstructor
////@RequestMapping("/api/files")
//public class FilaManagerController {
//
// @Autowired
// private FileStorageService fileStorageService;
// private static final Logger log = Logger.getLogger(FilaManagerController.class.getName());
//
// @PostMapping("/upload-file")
// public boolean uploadFile(@RequestParam("file") MultipartFile file) {
// try {
// fileStorageService.saveFile(file);
// return true;
// } catch (IOException e) {
// log.log(Level.SEVERE, "Exception during upload", e);
// }
// return false;
// }
//
// @GetMapping("/download")
// public ResponseEntity<Resource> downloadFile(@RequestParam("fileName") String filename) {
// log.log(Level.INFO, "[NORMAL] Download with /download");
// try {
// var fileToDownload = fileStorageService.getDownloadFile(filename);
// return ResponseEntity.ok()
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
// .contentLength(fileToDownload.length())
// .contentType(MediaType.APPLICATION_OCTET_STREAM)
// .body(new InputStreamResource(Files.newInputStream(fileToDownload.toPath())));
// } catch (Exception e) {
// return ResponseEntity.notFound().build();
// }
// }
//
//
//
//
//
//
//
// @GetMapping("/download-faster")
// public ResponseEntity<Resource> downloadFileFaster(@RequestParam("fileName") String filename) {
// log.log(Level.INFO, "[FASTER] Download with /download-faster");
// try {
// var fileToDownload = fileStorageService.getDownloadFile(filename);
// return ResponseEntity.ok()
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
// .contentLength(fileToDownload.length())
// .contentType(MediaType.APPLICATION_OCTET_STREAM)
// .body(new FileSystemResource(fileToDownload));
// } catch (Exception e) {
// return ResponseEntity.notFound().build();
// }
// }
//
//}
//package br.com.treinaweb.twjobs.api.files;
//
//import org.springframework.stereotype.Controller;
//import org.springframework.ui.Model;
//import org.springframework.web.bind.annotation.GetMapping;
//
//import java.io.File;
//import java.io.IOException;
//import java.nio.file.DirectoryStream;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.util.stream.Collectors;
//import java.util.stream.StreamSupport;
//
//@Controller
//public class FileManagerGuiController {
//
// @GetMapping("/uploader")
// public String uploader() {
// return "uploader";
// }
//
// @GetMapping("/list-files")
// public String listFiles(Model model) throws IOException {
// try (DirectoryStream<Path> stream = Files.newDirectoryStream(new File(FileStorageService.STORAGE_DIRECTORY).toPath())) {
// model.addAttribute("files",
// StreamSupport.stream(stream.spliterator(), false)
// .map(Path::getFileName)
// .map(Path::toString)
// .collect(Collectors.toList()));
// }
// return "list_files";
// }
//}
\ No newline at end of file
//package br.com.treinaweb.twjobs.api.files;
//
//import org.springframework.stereotype.Service;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.File;
//import java.io.FileNotFoundException;
//import java.io.IOException;
//import java.nio.file.Files;
//import java.nio.file.StandardCopyOption;
//import java.util.Objects;
//
//@Service
//public class FileStorageService {
//
// public static final String STORAGE_DIRECTORY = "C:\\fotos-java\\contato-disco-2";
//
// public void saveFile(MultipartFile fileToSave) throws IOException {
// if (fileToSave == null) {
// throw new NullPointerException("fileToSave is null");
// }
// var targetFile = new File(STORAGE_DIRECTORY + File.separator + fileToSave.getOriginalFilename());
// if (!Objects.equals(targetFile.getParent(), STORAGE_DIRECTORY)) {
// throw new SecurityException("Unsupported filename!");
// }
// Files.copy(fileToSave.getInputStream(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
// }
//
// public File getDownloadFile(String fileName) throws Exception {
// if (fileName == null) {
// throw new NullPointerException("fileName is null");
// }
// var fileToDownload = new File(STORAGE_DIRECTORY + File.separator + fileName);
// if (!Objects.equals(fileToDownload.getParent(), STORAGE_DIRECTORY)) {
// throw new SecurityException("Unsupported filename!");
// }
// if (!fileToDownload.exists()) {
// throw new FileNotFoundException("No file named: " + fileName);
// }
// return fileToDownload;
// }
//}
package br.com.treinaweb.twjobs.api.fotos.controllers;
import br.com.treinaweb.twjobs.core.models.Disco;
import br.com.treinaweb.twjobs.core.models.User;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/fotos")
public class FotosRestController {
@Autowired
private final Disco disco;
@PostMapping
public void upload(@RequestParam MultipartFile foto, User user, String filetype){
String originalfilename = foto.getOriginalFilename();
disco.salvarFoto(foto, user, originalfilename.substring(originalfilename.lastIndexOf(".")+1));
}
}
package br.com.treinaweb.twjobs.api.jobs.assemblers;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.jobs.controllers.JobRestController;
import br.com.treinaweb.twjobs.api.jobs.controllers.JobSkillsRestController;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
@Component
public class JobAssembler implements SimpleRepresentationModelAssembler<JobResponse> {
@Override
public void addLinks(EntityModel<JobResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(JobRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(JobRestController.class).update(null, id))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(JobRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
var skillsLink = linkTo(methodOn(JobSkillsRestController.class).findSkillsByJobId(id))
.withRel("skills")
.withType("GET");
resource.add(selfLink, updateLink, deleteLink, skillsLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<JobResponse>> resources) {
var selfLink = linkTo(methodOn(JobRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(JobRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.jobs.controllers;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import br.com.treinaweb.twjobs.core.exceptions.JobNotFoundException;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.JobRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/jobs/{id}")
public class CanidateRestController {
private final JobRepository jobRepository;
private final SecurityService securityService;
@PostMapping("/apply")
@TWJobsPermissions.IsCandidate
public ResponseEntity<?> apply(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
job.getCandidates().add(securityService.getCurrentUser());
jobRepository.save(job);
return ResponseEntity.noContent().build();
}
}
package br.com.treinaweb.twjobs.api.jobs.controllers;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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;
import br.com.treinaweb.twjobs.api.jobs.assemblers.JobAssembler;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.api.jobs.mappers.JobMapper;
import br.com.treinaweb.twjobs.core.exceptions.JobNotFoundException;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.JobRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/jobs")
public class JobRestController {
private final JobMapper jobMapper;
private final JobAssembler jobAssembler;
private final JobRepository jobRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<JobResponse> pagedResourcesAssembler;
@GetMapping
public CollectionModel<EntityModel<JobResponse>> findAll(Pageable pageable) {
var jobs = jobRepository.findAll(pageable)
.map(jobMapper::toJobResponse);
return pagedResourcesAssembler.toModel(jobs, jobAssembler);
}
@GetMapping("/{id}")
public EntityModel<JobResponse> findById(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
var jobResponse = jobMapper.toJobResponse(job);
return jobAssembler.toModel(jobResponse);
}
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<JobResponse> create(@RequestBody @Valid JobRequest jobRequest) {
var job = jobMapper.toJob(jobRequest);
job.setCompany(securityService.getCurrentUser());
job = jobRepository.save(job);
var jobResponse = jobMapper.toJobResponse(job);
return jobAssembler.toModel(jobResponse);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsOwner
public EntityModel<JobResponse> update(
@RequestBody @Valid JobRequest jobRequest,
@PathVariable Long id
) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
var jobData = jobMapper.toJob(jobRequest);
BeanUtils.copyProperties(jobData, job, "id", "company", "candidates");
job = jobRepository.save(job);
var jobResponse = jobMapper.toJobResponse(job);
return jobAssembler.toModel(jobResponse);
}
@DeleteMapping("/{id}")
@TWJobsPermissions.IsOwner
public ResponseEntity<?> delete(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
jobRepository.delete(job);
return ResponseEntity.noContent().build();
}
}
package br.com.treinaweb.twjobs.api.jobs.controllers;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.api.skills.mappers.SkillMapper;
import br.com.treinaweb.twjobs.core.exceptions.JobNotFoundException;
import br.com.treinaweb.twjobs.core.repositories.JobRepository;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/jobs/{id}/skills")
public class JobSkillsRestController {
private final SkillMapper skillMapper;
private final JobRepository jobRepository;
@GetMapping
public List<SkillResponse> findSkillsByJobId(@PathVariable Long id) {
var job = jobRepository.findById(id)
.orElseThrow(JobNotFoundException::new);
return job.getSkills()
.stream()
.map(skillMapper::toSkillResponse)
.toList();
}
}
package br.com.treinaweb.twjobs.api.jobs.dtos;
import java.math.BigDecimal;
import java.util.List;
import br.com.treinaweb.twjobs.core.enums.JobLevel;
import br.com.treinaweb.twjobs.core.enums.JobType;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class JobRequest {
@NotEmpty
@Size(min = 5, max = 100)
private String title;
@NotEmpty
@Size(min = 10, max = 255)
private String description;
@NotEmpty
@Size(min = 3, max = 100)
private String location;
@NotNull
private JobType type;
@NotNull
private JobLevel level;
@NotNull
@Positive
private BigDecimal salary;
@NotEmpty
private List<Long> skills;
}
package br.com.treinaweb.twjobs.api.jobs.dtos;
import java.math.BigDecimal;
import br.com.treinaweb.twjobs.core.enums.JobLevel;
import br.com.treinaweb.twjobs.core.enums.JobType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class JobResponse {
private Long id;
private String title;
private String description;
private String company;
private String location;
private JobType type;
private JobLevel level;
private BigDecimal salary;
}
package br.com.treinaweb.twjobs.api.jobs.mappers;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.core.models.Job;
public interface JobMapper {
JobResponse toJobResponse(Job job);
Job toJob(JobRequest jobRequest);
}
package br.com.treinaweb.twjobs.api.jobs.mappers;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.core.models.Job;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class ModelMapperJobMapper implements JobMapper {
private final ModelMapper modelMapper;
@Override
public JobResponse toJobResponse(Job job) {
return modelMapper.map(job, JobResponse.class);
}
@Override
public Job toJob(JobRequest jobRequest) {
return modelMapper.map(jobRequest, Job.class);
}
}
package br.com.treinaweb.twjobs.api.navios;
import br.com.treinaweb.twjobs.core.models.Navio;
import br.com.treinaweb.twjobs.core.repositories.NavioRepository;
import br.com.treinaweb.twjobs.core.services.CadastroNavioService;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@AllArgsConstructor
@RestController
@RequestMapping("/api/navios")
public class NavioController {
private final CadastroNavioService cadastroNavioService;
private final NavioRepository navioRepository;
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public Navio adicionar(@Valid @RequestBody Navio navio) {
return cadastroNavioService.salvar(navio);
}
@GetMapping
public List<Navio> listar() {
return navioRepository.findAll();
}
@PutMapping("/{navioId}")
public ResponseEntity<Navio> atualizar(@Valid @PathVariable Long navioId, @Valid @RequestBody Navio navio) {
if(!navioRepository.existsById(navioId)) {
return ResponseEntity.notFound().build();
}
navio.setId(navioId);
Navio navioAtualizado = cadastroNavioService.salvar(navio);
return ResponseEntity.ok(navioAtualizado);
}
}
//package br.com.treinaweb.twjobs.api.ships.assemblers;
//
//import br.com.treinaweb.twjobs.api.ships.controllers.SkillRestController;
//import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
//import org.springframework.hateoas.CollectionModel;
//import org.springframework.hateoas.EntityModel;
//import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
//import org.springframework.stereotype.Component;
//
//import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
//import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
//
//@Component
//public class SkillAssembler implements SimpleRepresentationModelAssembler<SkillResponse> {
//
// @Override
// public void addLinks(EntityModel<SkillResponse> resource) {
// var id = resource.getContent().getId();
//
// var selfLink = linkTo(methodOn(SkillRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
//
// var updateLink = linkTo(methodOn(SkillRestController.class).update(id, null))
// .withRel("update")
// .withType("PUT");
//
// var deleteLink = linkTo(methodOn(SkillRestController.class).delete(id))
// .withRel("delete")
// .withType("DELETE");
//
//
// resource.add(selfLink, updateLink, deleteLink);
// }
//
// @Override
// public void addLinks(CollectionModel<EntityModel<SkillResponse>> resources) {
// var selfLink = linkTo(methodOn(SkillRestController.class).findAll(null))
// .withSelfRel()
// .withType("GET");
//
// var createLink = linkTo(methodOn(SkillRestController.class).create(null))
// .withRel("create")
// .withType("POST");
//
// resources.add(selfLink, createLink);
// }
//
//}
package br.com.treinaweb.twjobs.api.ships.controllers;
//import br.com.treinaweb.twjobs.api.ships.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.api.skills.mappers.SkillMapper;
import br.com.treinaweb.twjobs.core.exceptions.SkillNotFoundException;
import br.com.treinaweb.twjobs.core.models.Ship;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.ShipRepository;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/ships")
public class ShipRestController {
private final ShipRepository shipRepository;
@GetMapping
@TWJobsPermissions.IsCompany
public List<Ship> getAll(){
return shipRepository.findAll();
}
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public Ship add(@RequestBody Ship ship) {
return shipRepository.save(ship);
}
// private final SkillMapper skillMapper;
// private final SkillAssembler skillAssembler;
// private final SkillRepository skillRepository;
// private final PagedResourcesAssembler<SkillResponse> pagedResourcesAssembler;
// @GetMapping
// public CollectionModel<EntityModel<SkillResponse>> findAll(Pageable pageable) {
// var skills = skillRepository.findAll(pageable)
// .map(skillMapper::toSkillResponse);
//
// return pagedResourcesAssembler.toModel(skills, skillAssembler);
// }
// @GetMapping("/{id}")
// public EntityModel<SkillResponse> findById(@PathVariable Long id) {
// var skill = skillRepository.findById(id)
// .map(skillMapper::toSkillResponse)
// .orElseThrow(SkillNotFoundException::new);
//
// return skillAssembler.toModel(skill);
// }
// @PostMapping
// @TWJobsPermissions.IsCompany
// @ResponseStatus(code = HttpStatus.CREATED)
// public EntityModel<SkillResponse> create(@Valid @RequestBody SkillRequest skillRequest) {
// var skill = skillMapper.toSkill(skillRequest);
// skill = skillRepository.save(skill);
// var skillResponse = skillMapper.toSkillResponse(skill);
// return skillAssembler.toModel(skillResponse);
// }
// @PutMapping("/{id}")
// @TWJobsPermissions.IsCompany
// public EntityModel<SkillResponse> update(
// @PathVariable Long id,
// @Valid @RequestBody SkillRequest skillRequest
// ) {
// var skill = skillRepository.findById(id)
// .orElseThrow(SkillNotFoundException::new);
// BeanUtils.copyProperties(skillRequest, skill, "id");
// skill = skillRepository.save(skill);
// var skillResponse = skillMapper.toSkillResponse(skill);
// return skillAssembler.toModel(skillResponse);
// }
// @DeleteMapping("/{id}")
// @TWJobsPermissions.IsCompany
// public ResponseEntity<?> delete(@PathVariable Long id) {
// var skill = skillRepository.findById(id)
// .orElseThrow(SkillNotFoundException::new);
// skillRepository.delete(skill);
// return ResponseEntity.noContent().build();
// }
}
package br.com.treinaweb.twjobs.api.ships.dtos;
import br.com.treinaweb.twjobs.core.validators.SkillNameIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ShipRequest {
@NotEmpty
@SkillNameIsUnique
private String imo;
}
package br.com.treinaweb.twjobs.api.ships.dtos;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class ShipResponse {
private Long id;
private String imo;
}
//package br.com.treinaweb.twjobs.api.ships.mappers;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//import lombok.RequiredArgsConstructor;
//import org.modelmapper.ModelMapper;
//import org.springframework.stereotype.Component;
//
//@Component
//@RequiredArgsConstructor
//public class ModelMapperSkillMapper implements SkillMapper {
//
// private final ModelMapper modelMapper;
//
// @Override
// public Skill toSkill(ShipRequest skillRequest) {
// return modelMapper.map(skillRequest, Skill.class);
// }
//
// @Override
// public ShipResponse toSkillResponse(Skill skill) {
// return modelMapper.map(skill, ShipResponse.class);
// }
//
//}
//package br.com.treinaweb.twjobs.api.ships.mappers;
//
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
//import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
//import br.com.treinaweb.twjobs.core.models.Skill;
//
//public interface SkillMapper {
//
// Skill toSkill(ShipRequest skillRequest);
// ShipResponse toSkillResponse(Skill skill);
//
//}
package br.com.treinaweb.twjobs.api.skills.assemblers;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.skills.controllers.SkillRestController;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
@Component
public class SkillAssembler implements SimpleRepresentationModelAssembler<SkillResponse> {
@Override
public void addLinks(EntityModel<SkillResponse> resource) {
var id = resource.getContent().getId();
var selfLink = linkTo(methodOn(SkillRestController.class).findById(id))
.withSelfRel()
.withType("GET");
var updateLink = linkTo(methodOn(SkillRestController.class).update(id, null))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(SkillRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(selfLink, updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<SkillResponse>> resources) {
var selfLink = linkTo(methodOn(SkillRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
var createLink = linkTo(methodOn(SkillRestController.class).create(null))
.withRel("create")
.withType("POST");
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.skills.controllers;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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;
import br.com.treinaweb.twjobs.api.skills.assemblers.SkillAssembler;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillRequest;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.api.skills.mappers.SkillMapper;
import br.com.treinaweb.twjobs.core.exceptions.SkillNotFoundException;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/skills")
public class SkillRestController {
private final SkillMapper skillMapper;
private final SkillAssembler skillAssembler;
private final SkillRepository skillRepository;
private final PagedResourcesAssembler<SkillResponse> pagedResourcesAssembler;
@GetMapping
public CollectionModel<EntityModel<SkillResponse>> findAll(Pageable pageable) {
var skills = skillRepository.findAll(pageable)
.map(skillMapper::toSkillResponse);
return pagedResourcesAssembler.toModel(skills, skillAssembler);
}
@GetMapping("/{id}")
public EntityModel<SkillResponse> findById(@PathVariable Long id) {
var skill = skillRepository.findById(id)
.map(skillMapper::toSkillResponse)
.orElseThrow(SkillNotFoundException::new);
return skillAssembler.toModel(skill);
}
@PostMapping
@TWJobsPermissions.IsCompany
@ResponseStatus(code = HttpStatus.CREATED)
public EntityModel<SkillResponse> create(@Valid @RequestBody SkillRequest skillRequest) {
var skill = skillMapper.toSkill(skillRequest);
skill = skillRepository.save(skill);
var skillResponse = skillMapper.toSkillResponse(skill);
return skillAssembler.toModel(skillResponse);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsCompany
public EntityModel<SkillResponse> update(
@PathVariable Long id,
@Valid @RequestBody SkillRequest skillRequest
) {
var skill = skillRepository.findById(id)
.orElseThrow(SkillNotFoundException::new);
BeanUtils.copyProperties(skillRequest, skill, "id");
skill = skillRepository.save(skill);
var skillResponse = skillMapper.toSkillResponse(skill);
return skillAssembler.toModel(skillResponse);
}
@DeleteMapping("/{id}")
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var skill = skillRepository.findById(id)
.orElseThrow(SkillNotFoundException::new);
skillRepository.delete(skill);
return ResponseEntity.noContent().build();
}
}
package br.com.treinaweb.twjobs.api.skills.dtos;
import br.com.treinaweb.twjobs.core.validators.SkillNameIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SkillRequest {
@NotEmpty
@SkillNameIsUnique
private String name;
}
package br.com.treinaweb.twjobs.api.skills.dtos;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class SkillResponse {
private Long id;
private String name;
}
package br.com.treinaweb.twjobs.api.skills.mappers;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillRequest;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class ModelMapperSkillMapper implements SkillMapper {
private final ModelMapper modelMapper;
@Override
public Skill toSkill(SkillRequest skillRequest) {
return modelMapper.map(skillRequest, Skill.class);
}
@Override
public SkillResponse toSkillResponse(Skill skill) {
return modelMapper.map(skill, SkillResponse.class);
}
}
package br.com.treinaweb.twjobs.api.skills.mappers;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillRequest;
import br.com.treinaweb.twjobs.api.skills.dtos.SkillResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
public interface SkillMapper {
Skill toSkill(SkillRequest skillRequest);
SkillResponse toSkillResponse(Skill skill);
}
package br.com.treinaweb.twjobs.api.users.assemblers;//package br.com.treinaweb.twjobs.api.ships.assemblers;
import br.com.treinaweb.twjobs.api.users.controllers.UsersCRUDRestController;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class UserAssembler implements SimpleRepresentationModelAssembler<UserResponse> {
@Override
public void addLinks(EntityModel<UserResponse> resource) {
var id = resource.getContent().getId();
// var selfLink = linkTo(methodOn(UsersCRUDRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
Link updateLink = null;
updateLink = linkTo(methodOn(UsersCRUDRestController.class).update(id, null))
.withRel("update")
.withType("PUT");
var deleteLink = linkTo(methodOn(UsersCRUDRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(
// selfLink,
updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<UserResponse>> resources) {
var selfLink = linkTo(methodOn(UsersCRUDRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
// Link createLink = null;
// try {
// createLink = linkTo(methodOn(UsersCRUDRestController.class).create(null, null))
// .withRel("create")
// .withType("POST");
// } catch (JsonProcessingException e) {
// throw new RuntimeException(e);
// }
resources.add(selfLink
//,
// createLink
);
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.api.users.controllers;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.api.users.assemblers.UserAssembler;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import br.com.treinaweb.twjobs.api.users.mappers.UserMapper;
import br.com.treinaweb.twjobs.api.vessels.assemblers.VesselAssembler;
import br.com.treinaweb.twjobs.api.vessels.mappers.VesselMapper;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.UserRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/users")
public class UsersCRUDRestController {
// private final UserMapper userMapper;
private final UserAssembler userAssembler;
private final UserMapper userMapper;
private final UserRepository userRepository;
private final SecurityService securityService;
private final PasswordEncoder passwordEncoder;
// private final UserAssembler userAssembler;
private final PagedResourcesAssembler<UserResponse> pagedResourcesAssembler;
@GetMapping
@TWJobsPermissions.IsCompany
public CollectionModel<EntityModel<UserResponse>> findAll(@PageableDefault(value = 15) Pageable pageable) {
var users = userRepository.findAll(pageable)
.map(userMapper::toUserResponse);
return pagedResourcesAssembler.toModel(users, userAssembler);
}
@PutMapping("/{id}")
@TWJobsPermissions.IsCompany
public User update(@PathVariable Long id, @RequestBody User user) {
Optional<User> userSaved = userRepository.findById(id);
//A única coisa que pode alterar até agora é o atributo SendEmail
user.setEmail(userSaved.get().getEmail());
user.setPassword(userSaved.get().getPassword());
user.setName(userSaved.get().getName());
user.setRole(userSaved.get().getRole());
user.setId(id);
Boolean check = userRepository.existsBySendEmail(user.getSendEmail());
if(user.getSendEmail() == Boolean.TRUE) {
if(check) {
user.setSendEmail(Boolean.FALSE);
throw new NegocioException("Você só pode ter 1 e-mail ativo");
}
}
//É NECESSÁRIO QUE O FRONT DESCRIPTOGRAFE
//var passwordHash = passwordEncoder.encode(user.getPassword());
//user.setPassword(passwordHash);
return userRepository.save(user);
}
@DeleteMapping("{id}")
@TWJobsPermissions
public ResponseEntity<Void> delete(@PathVariable Long id) {
Boolean check = userRepository.existsById(id);
Optional<User> user = userRepository.findById(id);
if(check) {
if(user != null) {
//user.deleteById(id);
throw new NegocioException("Error");
}
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.notFound().build();
}
}
}
package br.com.treinaweb.twjobs.api.users.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import jakarta.persistence.*;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserRequest {
private String name;
private String email;
private String password;
private Role role;
private Boolean sendEmail;
}
package br.com.treinaweb.twjobs.api.users.dtos;
import br.com.treinaweb.twjobs.core.enums.Role;
import jakarta.persistence.*;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private Long id;
private String name;
private String email;
private String password;
private Role role;
private Boolean sendEmail;
}
package br.com.treinaweb.twjobs.api.users.mappers;
import br.com.treinaweb.twjobs.api.users.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperUserCRUDMapper implements UserMapper {
private final ModelMapper modelMapper;
@Override
public User toUser(UserRequest userRequest) {
return modelMapper.map(userRequest, User.class);
}
@Override
public UserResponse toUserResponse(User user) {
return modelMapper.map(user, UserResponse.class);
}
}
package br.com.treinaweb.twjobs.api.users.mappers;
import br.com.treinaweb.twjobs.api.users.dtos.UserRequest;
import br.com.treinaweb.twjobs.api.users.dtos.UserResponse;
import br.com.treinaweb.twjobs.core.models.User;
public interface UserMapper {
User toUser(UserRequest userRequest);
UserResponse toUserResponse(User user);
}
package br.com.treinaweb.twjobs.api.vessels.assemblers;
import br.com.treinaweb.twjobs.api.vessels.controllers.VesselRestController;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.SimpleRepresentationModelAssembler;
import org.springframework.stereotype.Component;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
@Component
public class VesselAssembler implements SimpleRepresentationModelAssembler<VesselResponse> {
@Override
public void addLinks(EntityModel<VesselResponse> resource) {
var id = resource.getContent().getId();
// var selfLink = linkTo(methodOn(VesselRestController.class).findById(id))
// .withSelfRel()
// .withType("GET");
Link updateLink = null;
try {
updateLink = linkTo(methodOn(VesselRestController.class).update(null, id, null))
.withRel("update")
.withType("PUT");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
var deleteLink = linkTo(methodOn(VesselRestController.class).delete(id))
.withRel("delete")
.withType("DELETE");
resource.add(
// selfLink,
updateLink, deleteLink);
}
@Override
public void addLinks(CollectionModel<EntityModel<VesselResponse>> resources) {
var selfLink = linkTo(methodOn(VesselRestController.class).findAll(null))
.withSelfRel()
.withType("GET");
Link createLink = null;
try {
createLink = linkTo(methodOn(VesselRestController.class).create(null, null))
.withRel("create")
.withType("POST");
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
resources.add(selfLink, createLink);
}
}
package br.com.treinaweb.twjobs.api.vessels.controllers;
import br.com.treinaweb.twjobs.api.vessels.assemblers.VesselAssembler;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.api.vessels.mappers.VesselMapper;
import br.com.treinaweb.twjobs.core.exceptions.VesselNotFoundException;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.hateoas.EntityModel;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/vdatas")
public class VesselDataRestController {
private final VesselRepository vesselRepository;
private final VesselMapper vesselMapper;
private final VesselAssembler vesselAssembler;
@GetMapping("{imo}")
EntityModel<VesselResponse> ReturnVDataByImo(@PathVariable Long imo){
var vessel = vesselRepository.findByImo(imo)
.orElseThrow(VesselNotFoundException::new);
var vesselResponse = vesselMapper.toVesselResponse(vessel);
return vesselAssembler.toModel(vesselResponse);
}
}
package br.com.treinaweb.twjobs.api.vessels.controllers;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptRequest;
import br.com.treinaweb.twjobs.api.file.FileManagerController;
import br.com.treinaweb.twjobs.api.vessels.assemblers.VesselAssembler;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselRequest;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.api.vessels.mappers.VesselMapper;
import br.com.treinaweb.twjobs.core.enums.Role;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.exceptions.AceiteNotFoundException;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.exceptions.VesselNotFoundException;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Disco;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.permissions.TWJobsPermissions;
import br.com.treinaweb.twjobs.core.repositories.VesselCustomRepository;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.services.CadastroVesselService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static java.util.logging.Logger.global;
import static org.hibernate.type.descriptor.java.CoercionHelper.toLong;
//@CrossOrigin
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/vessels")
public class VesselRestController {
private final VesselAssembler vesselAssembler;
private final VesselMapper vesselMapper;
private final CadastroVesselService cadastroVesselService;
private final VesselRepository vesselRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<VesselResponse> pagedResourcesAssembler;
private final FileManagerController fileManagerController;
private final VesselCustomRepository vesselCustomRepository;
@Autowired
private ObjectMapper mapper;
@Autowired
private final Disco disco;
public void check_user(Vessel vessel){
if(securityService.getCurrentUser() != vessel.getUser() ) {
throw new NegocioException("Você não é proprietário do dado.");
}
}
@GetMapping
public CollectionModel<EntityModel<VesselResponse>> findAll(@PageableDefault(value = 15) Pageable pageable) {
User user = securityService.getCurrentUser();
Long userId = user.getId();
// if (user.getRole().equals(Role.COMPANY)) {
// throw new NegocioException("É company");
var vessels = vesselRepository.findAll(pageable)
.map(vesselMapper::toVesselResponse);
return pagedResourcesAssembler.toModel(vessels, vesselAssembler);
// } else if (user.getRole().equals(Role.CANDIDATE)) {
// // throw new NegocioException("É candidate");
// var vessels = vesselRepository.findAllByUserId(pageable, userId)
// .map(vesselMapper::toVesselResponse);
// return pagedResourcesAssembler.toModel(vessels, vesselAssembler);
// }
// return null;
// return pagedResourcesAssembler.toModel(vessels, vesselAssembler);
}
// """
// Esse método retorna apenas os Vessels do Usuário. role CANDIDATE pra cima.
//
// """
// @GetMapping
// public CollectionModel<EntityModel<VesselResponse>> findAll(@PageableDefault(value = 15) Pageable pageable) {
////
// User user = securityService.getCurrentUser();
// Long userId = user.getId();
//
//// Precisa do Optional
// Page<VesselResponse>
// vessels = vesselRepository.findAllByUserId(pageable,userId)
// .map(vesselMapper::toVesselResponse);
//// .orElseThrow(VesselNotFoundException::new);
//
// return pagedResourcesAssembler.toModel(vessels, vesselAssembler);
// }
//
//
//// """
//// Esse método retorna todos os Vessels. `apenas` role COMPANY
////
//// """
// @GetMapping("/admin")
// @TWJobsPermissions.IsCompany
// public CollectionModel<EntityModel<VesselResponse>> admFindAll(@PageableDefault(value = 15) Pageable pageable) {
//
//
// var vessels = vesselRepository.findAll(pageable)
// .map(vesselMapper::toVesselResponse);
//// .orElseThrow(VesselNotFoundException::new);
//
// return pagedResourcesAssembler.toModel(vessels, vesselAssembler);
// }
//
//
//
//
// @GetMapping("/{id}")
// public EntityModel<VesselResponse> findById(@PathVariable Long id) {
//
// var vessel = vesselRepository.findById(id)
// .orElseThrow(VesselNotFoundException::new);
//
//// check_user(vessel);
//
// var vesselResponse = vesselMapper.toVesselResponse(vessel);
// return vesselAssembler.toModel(vesselResponse);
// }
// @GetMapping("/{id}")
// public EntityModel<VesselResponse> findById(@PathVariable Long id) {
//
// var vessel = vesselRepository.findById(id)
// .orElseThrow(VesselNotFoundException::new);
//
// check_user(vessel);
//
// var vesselResponse = vesselMapper.toVesselResponse(vessel);
// return vesselAssembler.toModel(vesselResponse);
// }
@GetMapping("statistics/count")
public Long howMany() {
return vesselRepository.countAllVessels();
}
@GetMapping("/custom")
public List<Vessel> findTest(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "imo", required = false) Long imo, @RequestParam(value = "categoria", required = false) String categoria, @RequestParam(value = "nome", required = false) String nome) {
List<Vessel> vessels = vesselCustomRepository.vesselsCustom(id, imo, categoria, nome);
// .stream()
// .map(acceptMapper::toAcceptResponse)
// .collect(Collectors.toList());
// List<Accept> acceptRespons;
// for(AcceptOk i : accepts){
//
// acceptRespons.add(acceptMapper.toAccept(i)) ;
// }
return vessels;
}
@Value("${contato.disco.raiz}")
private String raiz;
@Value("${contato.disco.diretorio-fotos}")
private String diretorioFotos;
private static final String STORAGE_DIRECTORY = "C:\\StoragePorto";
@ResponseStatus(HttpStatus.CREATED)
// @TWJobsPermissions.IsCompany
@PostMapping
public EntityModel<VesselResponse> create(@Valid @RequestParam(name="vesselRequestForm", required=true) String vesselRequestForm,
// @RequestParam(name="foto", required=true) List<MultipartFile> fotos
@RequestParam(name="foto", required=true) MultipartFile foto
) throws JsonProcessingException {
// List<String> pathsList = new ArrayList<>();
// Itera sobre a lista de arquivos enviados
// for (MultipartFile foto : fotos) {
// if (!foto.isEmpty()) {
//// throw new NegocioException("Fotos não é vazio");
// fileManagerController.uploadFile(foto);
//// pathsList.add(foto.getOriginalFilename());
// }
// }
//verifica extensao
String filename = foto.getOriginalFilename();
String extension = null;
int dotIndex = filename.lastIndexOf(".");
if (dotIndex >= 0) {
extension = filename.substring(dotIndex + 1);
}
String[] extensions = {"txt", "zip", "pdf"};
Boolean verifica = false;
if(extension!=null) {
for(String i : extensions){
if(i.equals(extension) ) {
verifica =true;
break;
}
}
if(!verifica){
throw new NegocioException(extension);
}
}
fileManagerController.uploadFile(foto);
// String originalfilename = foto.getOriginalFilename();
//
// disco.salvarFoto(foto, securityService.getCurrentUser(), originalfilename.substring(originalfilename.lastIndexOf("/")+1));
LocalDate date = LocalDate.now();
// ObjectMapper mapper = new ObjectMapper();
// mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
// VesselRequest vesselRequestOk = mapper.readValue(vesselRequest, new TypeReference<VesselRequest>(){});
VesselRequest vesselRequest = mapper.readValue(vesselRequestForm, VesselRequest.class);
// var vessel = vesselMapper.toVessel(vesselRequestForm);
var vessel = vesselMapper.toVessel(vesselRequest);
// if (!pathsList.isEmpty()) {
// vessel.setPath(String.join("/%", pathsList)); // Adiciona todas as URLs, separadas por vírgula, por exemplo
// }
if(foto!=null) {
vessel.setPath(foto.getOriginalFilename());
}
// vessel.setPath(raiz+"\\"+diretorioFotos+"\\"+securityService.getCurrentUser().getId()+"--"+String.valueOf(date)+"."+foto.getContentType());
vessel.setUser(securityService.getCurrentUser());
//Tem que adicionar a validação se o tamanho do IMO é igual à 8.
int[] fator = {7, 6, 5, 4, 3, 2};
Long l = vessel.getImo();
String imo = Long.toString(l);
int[] newImo = new int[imo.length()];
for(int i = 0; i < imo.length(); i++) {
newImo[i] = imo.charAt(i) - '0';
}
int lastNumber = newImo[6];
int operation = (fator[0]*newImo[0])+(fator[1]*newImo[1])+(fator[2]*newImo[2])+(fator[3]*newImo[3])+(fator[4]*newImo[4])+(fator[5]*newImo[5]);
String operation_str = Integer.toString(operation);
int[] newOperation = new int[operation_str.length()];
for(int i = 0; i < operation_str.length(); i++) {
newOperation[i] = operation_str.charAt(i) - '0';
}
int nOpeLen = newOperation.length;
// if(lastNumber != newOperation[nOpeLen -1]) {
// throw new NegocioException("O IMO não segue o padrão");
// }
vessel.setSt_ver_vessel(VeriStatus.valueOf("N"));
vessel = vesselRepository.save(vessel);
var vesselResponse = vesselMapper.toVesselResponse(vessel);
return vesselAssembler.toModel(vesselResponse);
}
/* @GetMapping
@TWJobsPermissions.IsCompany
public List<Vessel> listar() {
return vesselRepository.findAll();
}*/
/* @PutMapping("/{vesselId}")
public ResponseEntity<Vessel> atualizar(@Valid @PathVariable Long vesselId, @Valid @RequestBody Vessel vessel) {
if(!vesselRepository.existsById(vesselId)) {
return ResponseEntity.notFound().build();
}
vessel.setId(vesselId);
vessel.setSt_ver_vessel(VeriStatus.valueOf("N"));
Vessel vesselAtualizado = cadastroVesselService.salvar(vessel);
return ResponseEntity.ok(vesselAtualizado);
}*/
@PutMapping("/{id}")
// @TWJobsPermissions.IsOwner
// @TWJobsPermissions.IsCompany
public EntityModel<VesselResponse> update(
// @RequestBody @Valid VesselRequest vesselRequest,
// @PathVariable Long id
@Valid @RequestParam(name="vesselRequestForm", required=true) String vesselRequestForm, @PathVariable Long id, @RequestParam(name="foto", required=false) MultipartFile foto
) throws JsonProcessingException {
VesselRequest vesselRequest = mapper.readValue(vesselRequestForm, VesselRequest.class);
//verifica extensao
String filename = foto.getOriginalFilename();
String extension = null;
int dotIndex = filename.lastIndexOf(".");
if (dotIndex >= 0) {
extension = filename.substring(dotIndex + 1);
}
String[] extensions = {"txt", "zip", "pdf"};
Boolean verifica = false;
if(extension!=null) {
for(String i : extensions){
if(i.equals(extension) ) {
verifica =true;
break;
}
}
if(!verifica){
throw new NegocioException(extension);
}
}
var vessel = vesselRepository.findById(id)
.orElseThrow(AceiteNotFoundException::new);
var vesselData = vesselMapper.toVessel(vesselRequest);
vesselData.setId(id);
// check_user(vessel);
// vessel.setSt_ver_vessel(vessel.getSt_ver_vessel());
// vessel.setStatus(vessel.getStatus());
// var vesselData = vesselMapper.toVessel(vesselRequest);
//Resolve o problema do update.
// vesselData.setSt_ver_vessel(vessel.getSt_ver_vessel());
// vesselData.setStatus(vessel.getStatus());
//TEMP
var path = vessel.getPath();
//TEMP
if(foto!=null) {
vessel.setPath(foto.getOriginalFilename());
fileManagerController.uploadFile(foto);
//SE NÃO ENVIAR NENHUM ARQUIVO
} else {
vessel.setPath(path);
}
//TEMP
BeanUtils.copyProperties(vesselData, vessel, "id");
// if(vesselData.getPath()==null) {
// vessel.setPath(path);
// }
//TEMP
vessel = vesselRepository.save(vesselData);
// vesselData.setId(id);
// vessel = vesselRepository.save(vessel);
// vessel = vesselRepository.save(vessel);
var vesselResponse = vesselMapper.toVesselResponse(vessel);
return vesselAssembler.toModel(vesselResponse);
}
@DeleteMapping("/{id}")
// @TWJobsPermissions.IsOwner
@TWJobsPermissions.IsCompany
public ResponseEntity<?> delete(@PathVariable Long id) {
var vessel = vesselRepository.findById(id)
.orElseThrow(VesselNotFoundException::new);
vesselRepository.delete(vessel);
return ResponseEntity.noContent().build();
}
// Continuar colocando os métodos e substituindo por vessels.
// Depois corrigir os objetos que talvez ainda não existam
// Testar o cadastro de um vessel pra ver se guarda o user_id
}
package br.com.treinaweb.twjobs.api.vessels.dtos;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.validators.SkillNameIsUnique;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
import org.springframework.web.multipart.MultipartFile;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VesselRequest {
// AJEITAR
//COMENTEI ID, SE DER ERRO É ISSO AQUI
//private Long id;
// private Long user;
//not empty não está funcionando. Ajeiter.
// @NotEmpty
// @VesselImoIsUnique
@NotNull(message = "IMO não pode ser nulo")
// @Size(min = 7, message = "IMO deve ter no mínimo 7 caracteres")
private Long imo;
private String mmsi;
private String nome;
//NOT NULL AND GREATER THAN ZERO
@NotNull(message = "LOA deve ser maior que zero")
// @Size(min = 1, max = 100, message = "LOA deve ter no mínimo 1 e no máximo 100 caracteres")
private Float loa;
private Float boca;
//NOT NULL AND GREATER THAN ZERO
@NotNull(message = "DWT deve ser maior que zero")
// @Size(min = 1, max = 100, message = "DWT deve ter no mínimo 1 e no máximo 100 caracteres")
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
//NOT NULL
// @NotEmpty
// @Size(min = 1, max = 100, message = "CATEGORIA deve ter no mínimo 1 e no máximo 100 caracteres")
private String categoria;
@JsonProperty("flag")
private String flag;
private String obs;
//private VeriStatus status;
//private VeriStatus st_ver_vessel;
private String path;
}
package br.com.treinaweb.twjobs.api.vessels.dtos;
import br.com.treinaweb.twjobs.core.validators.VesselImoIsUnique;
import jakarta.validation.constraints.NotEmpty;
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class VesselResponse {
private Long id;
private String user;
private Long imo;
private String mmsi;
private String nome;
private Float loa;
private Float boca;
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
private String categoria;
private String flag;
private String obs;
private String status;
private String st_ver_vessel;
private String path;
}
package br.com.treinaweb.twjobs.api.vessels.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselRequest;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
import br.com.treinaweb.twjobs.core.models.Vessel;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class ModelMapperVesselMapper implements VesselMapper {
private final ModelMapper modelMapper;
@Override
public Vessel toVessel(VesselRequest vesselRequest) {
return modelMapper.map(vesselRequest, Vessel.class);
}
@Override
public VesselResponse toVesselResponse(Vessel vessel) {
return modelMapper.map(vessel, VesselResponse.class);
}
}
package br.com.treinaweb.twjobs.api.vessels.mappers;//package br.com.treinaweb.twjobs.api.ships.mappers;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipRequest;
import br.com.treinaweb.twjobs.api.ships.dtos.ShipResponse;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselRequest;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.core.models.Skill;
import br.com.treinaweb.twjobs.core.models.Vessel;
public interface VesselMapper {
Vessel toVessel(VesselRequest vesselRequest);
VesselResponse toVesselResponse(Vessel vessel);
}
package br.com.treinaweb.twjobs.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import lombok.Data;
@Data
@Configuration
@ConfigurationProperties(prefix = "br.com.treinaweb.twjobs.jwt")
public class JwtConfigProperties {
private String accessSecret;
private Long accessExpiresIn;
private String refreshSecret;
private Long refreshExpiresIn;
}
package br.com.treinaweb.twjobs.config;
import java.util.List;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobRequest;
import br.com.treinaweb.twjobs.api.jobs.dtos.JobResponse;
import br.com.treinaweb.twjobs.core.models.Job;
import br.com.treinaweb.twjobs.core.models.Skill;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import lombok.RequiredArgsConstructor;
@Configuration
@RequiredArgsConstructor
public class ModelMapperConfig {
private final SkillRepository skillRepository;
@Bean
ModelMapper modelMapper() {
var modelmapper = new ModelMapper();
modelmapper.createTypeMap(JobRequest.class, Job.class)
.addMappings(mapper -> mapper
.using(toListOfSkills())
.map(JobRequest::getSkills, Job::setSkills)
);
modelmapper.createTypeMap(Job.class, JobResponse.class)
.addMappings(mapper -> mapper
.map(src -> src.getCompany().getName(), JobResponse::setCompany)
);
return modelmapper;
}
private Converter<List<Long>, List<Skill>> toListOfSkills() {
return context -> skillRepository.findAllById(context.getSource());
}
}
package br.com.treinaweb.twjobs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PasswordEnconderConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
package br.com.treinaweb.twjobs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import br.com.treinaweb.twjobs.api.common.filters.AccessTokenRequestFilter;
import lombok.RequiredArgsConstructor;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
private final AccessDeniedHandler accessDeniedHandler;
private final AccessTokenRequestFilter accessTokenRequestFilter;
private final AuthenticationEntryPoint authenticationEntryPoint;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(customizer -> customizer
.anyRequest().permitAll()
)
// .logout((logout) -> logout.logoutUrl("/teste/logout").permitAll())
.csrf(customizer -> customizer
.disable()
)
.sessionManagement(customizer -> customizer
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.exceptionHandling(customizer -> customizer
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
)
.addFilterBefore(accessTokenRequestFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
@Bean
AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration
) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
package br.com.treinaweb.twjobs.core.enums;
public enum AceiteStatus {
Y,
N;
}
package br.com.treinaweb.twjobs.core.enums;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
public enum CategoriaVessel {
G_LIQUIDO,
G_SOLIDO,
CARGA_GERAL;
}
package br.com.treinaweb.twjobs.core.enums;
public enum EmailActivation {
enable,
disable
}
package br.com.treinaweb.twjobs.core.enums;
public enum JobLevel {
JUNIOR,
MID_LEVEL,
SENIOR;
}
package br.com.treinaweb.twjobs.core.enums;
public enum JobType {
FULL_TIME,
PART_TIME,
FREELANCE,
INTERSHIP,
TEMPORARY;
}
package br.com.treinaweb.twjobs.core.enums;
public enum Role {
COMPANY,
CANDIDATE;
}
package br.com.treinaweb.twjobs.core.enums;
public enum VeriStatus {
Y,
NE,
N;
}
package br.com.treinaweb.twjobs.core.exceptions;
public class AcceptNotFoundException extends ModelNotFoundException{
public AcceptNotFoundException(){super("Accept not found.");}
public AcceptNotFoundException(String message){super(message);}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class AceiteNotFoundException extends ModelNotFoundException{
public AceiteNotFoundException() {
super("Aceite not found");
}
public AceiteNotFoundException(String message) {
super(message);
}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class BercoNotFoundException extends ModelNotFoundException{
public BercoNotFoundException(){ super("Berço não encontrado."); }
public BercoNotFoundException(String message) {super(message);}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class BlackListedNotFoundException extends ModelNotFoundException{
public BlackListedNotFoundException(){super("BlackListed not found.");}
public BlackListedNotFoundException(String message) {
super(message);
}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class JobNotFoundException extends ModelNotFoundException {
public JobNotFoundException() {
super("Job not found");
}
public JobNotFoundException(String message) {
super(message);
}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class JwtServiceException extends RuntimeException {
public JwtServiceException(String message) {
super(message);
}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class ModelNotFoundException extends RuntimeException {
public ModelNotFoundException(String message) {
super(message);
}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class NegocioException extends RuntimeException{
public NegocioException(String message) {
super(message);
}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class SkillNotFoundException extends ModelNotFoundException {
public SkillNotFoundException() {
super("Skill not found");
}
public SkillNotFoundException(String message) {
super(message);
}
}
package br.com.treinaweb.twjobs.core.exceptions;
public class VesselNotFoundException extends ModelNotFoundException{
public VesselNotFoundException(){ super("A embarcação não foi encontrada."); }
public VesselNotFoundException(String message){ super(message); }
}
package br.com.treinaweb.twjobs.core.models;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import br.com.treinaweb.twjobs.core.enums.CategoriaVessel;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.*;
import org.springframework.data.jpa.repository.Modifying;
import java.util.List;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded=true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Accept {
// TESTAR
@Id
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ToString.Include
@ManyToOne
private User user;
// NOT NULL
@ToString.Include
@ManyToOne(cascade = CascadeType.ALL)
private Vessel vessel;
// NOT NULL
@Column( nullable = false, length = 50)
private Long imo;
// < NOT NULL
@Column(name="data_accept", nullable = false, length = 100)
private String dataAccept;
@Column(nullable = false, length = 100)
private String data_create;
@Column(nullable = false, length = 100)
private String data_update;// >
@Column(nullable = false, length = 100)
private String time_accept;
@Column(nullable = false, length = 100)
private String time_create;
@Column(nullable = false, length = 100)
private String time_update;
private String obs;
private String restricoes;
@Column( columnDefinition = "varchar(9) DEFAULT 0", nullable = true, length = 9)
private String codigo;
// @Column(nullable = false, length = 20)
// @Enumerated(EnumType.STRING)
// private AceiteStatus status;
// NOT NULL
// Y -> 1; NE -> 2; N-> 3
@Column( columnDefinition = "CHAR(50) DEFAULT 'N'", nullable = false, length = 50)
// @Enumerated(EnumType.STRING)
private String status;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(
name="accept_berco",
joinColumns = @JoinColumn(name="accept_id"),
inverseJoinColumns = @JoinColumn(name="berco_id")
)
@JsonIgnoreProperties("accept")
private List<Berco> bercos;
// Assim, em name eu defino o nome da tabela intermediária.
// Em joiColumns em digo o nome da tabela mais forte.]
// E em inverseJoinColumns eu defino o nome da outra tabela que irá compor accept_berco.
// Dados navio
private String mmsi;
private String nome;
// NOT NULL
@Column( nullable = false, length = 100)
private Float loa;
private Float boca;
// NOT NULL
@Column( nullable = false, length = 100)
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
// NOT NULL
@Column( nullable = false, length = 100)
private String categoria;
private Integer flag;
// NOT NULL
@Column(nullable = false, length = 10)
private Float calado_entrada;
// NOT NULL
@Column(nullable = false, length = 10)
private Float calado_saida;
@Column(length=500)
private String path;
// @Column(nullable = false, length = 20)
// @Enumerated(EnumType.STRING)
// private AceiteStatus status;
}
package br.com.treinaweb.twjobs.core.models;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import jakarta.persistence.*;
import lombok.*;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Aceite {
@Id
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ToString.Include
@ManyToOne
private User user;
@ManyToOne(cascade = CascadeType.ALL)
private Vessel vessel;
private Long imo;
@Column(nullable = false, length = 20)
@Enumerated(EnumType.STRING)
private AceiteStatus status;
}
package br.com.treinaweb.twjobs.core.models;
import br.com.treinaweb.twjobs.core.enums.CategoriaVessel;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.*;
import java.util.List;
@Data
@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Berco {
// AJEITAR
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@EqualsAndHashCode.Include
private Long id;
private Long nome;
private Long compri_estrutural;
private Long compri_util;
private Float dwt;
private Long largura;
private Long profundidade;
private Float calado_max;
private Float boca_max;
private Float loa_max;
@ManyToMany(mappedBy = "bercos", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnoreProperties("bercos")
private List<Accept> accepts;
// Irá procurar uma propriedade chamada books dentro da classe Accepts.
// E fará a ligação entre as duas.
// O JsonIgnoreProperties serve para evitar uma
// @Column( columnDefinition = "ENUM('G_LIQUIDO','G_SOLIDO','CARGA_GERAL')", nullable = true, length = 50)
// @Enumerated(EnumType.STRING)
// private CategoriaVessel categoria;
@Column( nullable = false, length = 255)
private String categoria;
}
package br.com.treinaweb.twjobs.core.models;
import jakarta.persistence.*;
import lombok.*;
@Data
@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class BlackList {
// TESTAR
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@EqualsAndHashCode.Include
private Long id;
@ToString.Include
@ManyToOne
private User user;
// NÃO COLOCAREMOS RELACIONAMENTO COM VESSEL PRA EVITAR PRENDÊ-LO(POR ENQUANTO)
@Column( nullable = false, length = 50)
private Long imo;
@Column( nullable = false)
private String reason;
@Column(nullable = false, length = 100)
private String data_blacklisted;
@Column(nullable = false, length = 100)
private String data_create;
@Column(nullable = false, length = 100)
private String data_update;
@Column(nullable = false, length = 100)
private String time_blacklisted;
@Column(nullable = false, length = 100)
private String time_create;
@Column(nullable = false, length = 100)
private String time_update;
// Dados navio
private String mmsi;
private String nome;
// NOT NULL
@Column( nullable = false, length = 100)
private Float loa;
private Float boca;
// NOT NULL
@Column( nullable = false, length = 100)
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
// NOT NULL
@Column( nullable = false, length = 100)
private String categoria;
private Integer flag;
// NOT NULL
@Column(nullable = false, length = 10)
private Float calado_entrada;
// NOT NULL
@Column(nullable = false, length = 10)
private Float calado_saida;
}
package br.com.treinaweb.twjobs.core.models;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.chrono.IsoChronology;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDate;
@Component
public class Disco {
@Value("${contato.disco.raiz}")
private String raiz;
@Value("${contato.disco.diretorio-fotos}")
private String diretorioFotos;
LocalDate date = LocalDate.now();
public void salvarFoto(MultipartFile foto, User user, String filetype) {
this.salvar(this.diretorioFotos, foto, user, filetype);
}
public void salvar(String diretorio, MultipartFile arquivo, User user, String filetype) {
Path diretorioPath = Paths.get(this.raiz, diretorio);
String filename = user.getId() +"--"+String.valueOf(date)+"."+filetype;
// Path arquivoPath = diretorioPath.resolve(Objects.requireNonNull(arquivo.getOriginalFilename()));
Path arquivoPath = diretorioPath.resolve(Objects.requireNonNull(filename));
try {
Files.createDirectories(diretorioPath);
arquivo.transferTo(arquivoPath.toFile());
} catch (IOException e) {
throw new RuntimeException("Problemas na tentativa de salvar arquivo.", e);
}
}
}
package br.com.treinaweb.twjobs.core.models;
import br.com.treinaweb.twjobs.core.enums.EmailActivation;
import jakarta.persistence.*;
import lombok.*;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded=true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class EmailSend {
@Id
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ToString.Include
@ManyToOne
private User user;
@Column(nullable = false, length = 100)
private String content;
@Column(nullable = false, length = 20)
@Enumerated(EnumType.STRING)
private EmailActivation status;
}
package br.com.treinaweb.twjobs.core.models;
import java.math.BigDecimal;
import java.util.List;
import br.com.treinaweb.twjobs.core.enums.JobLevel;
import br.com.treinaweb.twjobs.core.enums.JobType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Job {
@Id
@ToString.Include
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ToString.Include
@Column(nullable = false, length = 100)
private String title;
@Column(nullable = false)
private String description;
@Column(nullable = false, length = 100)
private String location;
@Column(nullable = false, length = 9)
@Enumerated(EnumType.STRING)
private JobType type;
@Column(nullable = false, length = 9)
@Enumerated(EnumType.STRING)
private JobLevel level;
@Column(nullable = false, scale = 2)
private BigDecimal salary;
@ManyToMany
private List<Skill> skills;
@ManyToOne(optional = false)
private User company;
@ManyToMany
private List<User> candidates;
}
package br.com.treinaweb.twjobs.core.models;
import br.com.treinaweb.twjobs.core.validators.ValidationGroups;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Entity
@Getter
@Setter
public class Navio {
@NotNull(groups = ValidationGroups.NavioId.class)
@EqualsAndHashCode.Include
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private Long imo;
@NotBlank
@NotNull
@Size(max=60)
private String mmsi;
@NotBlank
@NotNull
@Size(max=50)
private String nome;
@NotNull
private float loa;
@NotNull
private float boca;
@NotNull
private float dwt;
@NotNull
private float pontal;
@NotNull
private float ponte_mfold;
@NotNull
private float mfold_quilha;
@NotNull
private char categoria;
@NotNull
private int flag;
@NotBlank
@NotNull
private String obs;
@NotNull
private char status;
}
package br.com.treinaweb.twjobs.core.models;
import jakarta.persistence.*;
import lombok.*;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Ship {
@Id
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true, length = 50)
private String imo;
}
package br.com.treinaweb.twjobs.core.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Skill {
@Id
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true, length = 50)
private String name;
}
package br.com.treinaweb.twjobs.core.models;
import br.com.treinaweb.twjobs.core.enums.Role;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.*;
@Data
@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class User {
@Id
@ToString.Include
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 100)
private String name;
@ToString.Include
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private Role role;
@Column(columnDefinition="boolean default false")
private Boolean sendEmail;
// POSSIVELMENTE ADICIONAR NOVA COLUNA(EMAIL-SEND) -- MAS NÃO AGORA
}
package br.com.treinaweb.twjobs.core.models;
import br.com.treinaweb.twjobs.core.enums.AceiteStatus;
import br.com.treinaweb.twjobs.core.enums.CategoriaVessel;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
import java.nio.file.Path;
import java.util.Optional;
@Data
@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString(onlyExplicitlyIncluded = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Vessel {
// TESTAR
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@EqualsAndHashCode.Include
private Long id;
@ToString.Include
@ManyToOne
private User user;
// NOT NULL
@Column( nullable = false, length = 50)
//@Column(nullable = false, unique = true, length = 50)
private Long imo;
private String mmsi;
private String nome;
// NOT NULL
@Column( nullable = false, length = 100)
private Float loa;
private Float boca;
// NOT NULL
@Column( nullable = false, length = 100)
private Float dwt;
private Float pontal;
private Float ponte_mfold;
private Float mfold_quilha;
// NOT NULL
@Column( nullable = false, length = 100)
private String categoria;
// private Integer flag;
@Column(nullable = true, length = 255)
private String flag;
private String obs;
@Column(nullable = true, length = 10)
private Float calado_entrada;
@Column(nullable = true, length = 10)
private Float calado_saida;
// @Column(nullable = false, length = 20)
// @Enumerated(EnumType.STRING)
// private AceiteStatus status;
// CAN BE NULL
// @Column( columnDefinition = "ENUM('Y','NE','N') DEFAULT 'N'", nullable = true, length = 20)
// @Enumerated(EnumType.STRING)
@Column( columnDefinition = "CHAR(50) DEFAULT 'N'", nullable = true, length = 50)
private String status;
// DELETAR TABELA
@Column( columnDefinition = "ENUM('Y','NE','N') DEFAULT 'N'", nullable = true, length = 20)
@Enumerated(EnumType.STRING)
private VeriStatus st_ver_vessel;
@Column(length=500)
private String path;
}
package br.com.treinaweb.twjobs.core.permissions;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.security.access.prepost.PreAuthorize;
public @interface TWJobsPermissions {
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("""
hasAuthority('COMPANY') and
@securityService.isOwner(principal.username, #id)
""")
public @interface IsOwner {}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAuthority('COMPANY')")
public @interface IsCompany {}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAuthority('CANDIDATE')")
public @interface IsCandidate {}
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.models.Accept;
import jakarta.persistence.EntityManager;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class AcceptCustomRepository {
private final EntityManager em;
public AcceptCustomRepository(EntityManager em) {
this.em = em;
}
// id
// imo
// status
// nome
public List<Accept> acceptsCustom(Long id, String imo, String status, String nome, String categoria, String data_create){
String query = "select A from Accept as A";
String condicao = " where ";
if(id!=null){
query += condicao + "A.id = :id";
condicao = " and ";
}
if(imo!=null){
query += condicao + "A.imo = :imo";
condicao = " and ";
}
if(status!=null){
query += condicao + "A.status = :status";
condicao = " and ";
}
if(nome!=null){
query += condicao + "A.nome LIKE :nome";
condicao = " and ";
}
if(categoria!=null){
query += condicao + "A.categoria = :categoria";
condicao = " and ";
}
if(data_create!=null){
query += condicao + "A.data_create LIKE :data_create";
condicao = " and ";
}
var q = em.createQuery(query, Accept.class);
if(id!=null){
q.setParameter("id", id);
}
if(imo!=null){
q.setParameter("imo", imo);
}
if(status!=null){
q.setParameter("status", status);
}
if(nome!=null){
q.setParameter("nome", "%"+nome+"%");
}
if(categoria!=null){
q.setParameter("categoria", categoria);
}
if(data_create!=null){
q.setParameter("data_create", "%"+data_create+"%");
}
return q.getResultList();
}
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Aceite;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.models.Vessel;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
public interface AcceptRepository extends JpaRepository<Accept, Long> {
Accept findFirstByOrderByDataAcceptDesc();
// Accept findFirstByOrderByPublicationDateDesc(Long imo);
// Accept findByImoOrderByImoDesc(Long imo);
@Query("SELECT p FROM Accept p ORDER BY p.id DESC LIMIT 1")
Accept FindLastAccept();
// Accept findTopByOrderByImoDesc(@Param("Imo")Long imo);
Accept findByImoOrderByIdDesc(Long imo);
Accept findTop1ByImoOrderByIdDesc(@Param("imo") Long imo);
Page<Accept> findAllByUser(Optional<User> user, Pageable pageable);
// SELECT a FROM ( SELECT b, ROW_NUMBER() OVER (ORDER BY id DESC) AS rn FROM accept ) AS subquery a WHERE a.rn = 1 AND a.imo=?1;
// @Query("SELECT a from( SELECT b, ROW_ )")
// @Query("SELECT a FROM Accept a WHERE a.codigo = '1' AND a.imo=?1" )
// Accept findAcceptByLastImo(Long imo);
// Funciona para PostgreeSQL e MySQL
// @Query("SELECT e FROM Accept e WHERE CAST(e.imo AS string) LIKE %:paramImo%")
// List<Accept> findAllByImoContaining(String paramImo);
Page<Accept> findAllByUserId(Pageable pageable, Long userId);
Optional<Accept> findByIdAndUserId(Long id, Long userId);
@Query("SELECT COUNT(u) FROM Accept u")
Long countAllAccepts();
@Query("SELECT a.status, COUNT(a) FROM Accept a GROUP BY a.status")
List<Object[]> countByStatus();
// List<Accept> findAllByImo(Long imo);
// Criar o find status by id.
// PEga o id do vessel que "findByImoAndFindFirstByOrderByPublicationDateDesc" retorna
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.models.Aceite;
import br.com.treinaweb.twjobs.core.models.Navio;
import br.com.treinaweb.twjobs.core.models.Vessel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface AceiteRepository extends JpaRepository<Aceite, Long>{
// boolean existsByCompanyEmailAndId(String companyEmail, Long id);
boolean findByImo(Long imo);
// Optional<Vessel> findByImo(Long imo);
// Long findVanessaByGorda(Long vane);
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.models.Berco;
import jakarta.persistence.EntityManager;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class BercoCustomRepository {
private final EntityManager em;
public BercoCustomRepository(EntityManager em) {
this.em = em;
}
// id
// imo
// status
// nome
public List<Berco> bercosCustom(Long id, String categoria, String nome){
String query = "select A from Berco as A";
String condicao = " where ";
if(id!=null){
query += condicao + "A.id = :id";
condicao = " and ";
}
if(categoria!=null){
query += condicao + "A.categoria = :categoria";
condicao = " and ";
}
if(nome!=null){
query += condicao + "A.nome = :nome";
condicao = " and ";
}
var q = em.createQuery(query, Berco.class);
if(id!=null){
q.setParameter("id", id);
}
if(categoria!=null){
q.setParameter("categoria", categoria);
}
if(nome!=null){
q.setParameter("nome", nome);
}
return q.getResultList();
}
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.models.Berco;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface BercoRepository extends JpaRepository<Berco, Long> {
// boolean existsByDwtAndExistsByLoa(Float dwt, Float loa);
boolean existsByNome(Long nome);
boolean existsByNomeAndIdNot(Long nome, Long id);
@Query("SELECT COUNT(u) FROM Berco u")
long countAllBercos();
// @Query("select b from berco b where b.nome >= 100 and b.nome <= 102")
// List<Berco> findAllBetween();
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.BlackList;
import jakarta.persistence.EntityManager;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class BlackListCustomRepository {
private final EntityManager em;
public BlackListCustomRepository(EntityManager em) {
this.em = em;
}
// id
// imo
// data_create
// time_create
public List<BlackList> blackListedsCustom(Long id, String imo, String data_create, String time_create){
String query = "select A from BlackList as A";
String condicao = " where ";
if(id!=null){
query += condicao + "A.id = :id";
condicao = " and ";
}
if(imo!=null){
query += condicao + "A.imo = :imo";
condicao = " and ";
}
if(data_create!=null){
query += condicao + "A.data_create LIKE :data_create";
condicao = " and ";
}
if(time_create!=null){
query += condicao + "A.time_create = :time_create";
condicao = " and ";
}
var q = em.createQuery(query, BlackList.class);
if(id!=null){
q.setParameter("id", id);
}
if(imo!=null){
q.setParameter("imo", imo);
}
if(data_create!=null){
q.setParameter("data_create", "%"+data_create+"%");
}
if(time_create!=null){
q.setParameter("time_create", "%"+time_create+"%");
}
return q.getResultList();
}
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.models.BlackList;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.Optional;
public interface BlackListRepository extends JpaRepository<BlackList, Long> {
Page<BlackList> findAllByUserId(Pageable pageable, Long userId);
boolean existsByImo(Long imo);
@Query("SELECT COUNT(u) FROM BlackList u")
long countAllBlackLists();
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.enums.EmailActivation;
import br.com.treinaweb.twjobs.core.models.EmailSend;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface EmailSendRepository extends JpaRepository<EmailSend, Long> {
List<EmailSend> findAllByUserId(Long userId);
Boolean existsByUserIdAndStatus(Long userId, EmailActivation emailStatus);
Boolean existsByUserIdAndId(Long userId, Long id);
EmailSend findByStatus(EmailActivation statusEmail);
}
package br.com.treinaweb.twjobs.core.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import br.com.treinaweb.twjobs.core.models.Job;
public interface JobRepository extends JpaRepository<Job, Long> {
boolean existsByCompanyEmailAndId(String companyEmail, Long id);
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.models.Navio;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface NavioRepository extends JpaRepository<Navio, Long> {
List<Navio> findByNome(String nome);
List<Navio> findByNomeContaining(String nome);
Optional<Navio> findByImo(Long imo);
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.models.Ship;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface ShipRepository extends JpaRepository<Ship, Long> {
@Override
Optional<Ship> findById(Long aLong);
}
package br.com.treinaweb.twjobs.core.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import br.com.treinaweb.twjobs.core.models.Skill;
public interface SkillRepository extends JpaRepository<Skill, Long> {
boolean existsByName(String name);
boolean existsByNameAndIdNot(String name, Long id);
}
package br.com.treinaweb.twjobs.core.repositories;
import java.util.List;
import java.util.Optional;
import br.com.treinaweb.twjobs.core.enums.EmailActivation;
import br.com.treinaweb.twjobs.core.enums.Role;
import org.springframework.data.jpa.repository.JpaRepository;
import br.com.treinaweb.twjobs.core.models.User;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
User findNameByEmail(String email);
//Como uso código SQL aqui então (talvez) dependendo do PC a sintaxe pode causar erro, ou não.
@Query(value = "SELECT role FROM User WHERE role = (SELECT role FROM User WHERE email=:customer) LIMIT 1;", nativeQuery = true)
List<Role> findTheRoleByEmail(@Param("customer") String email);
// ESTATÍSTICA
@Query("SELECT COUNT(u) FROM User u")
long countAllUsers();
Boolean existsBySendEmail(Boolean sendEmail);
void deleteById(Long id);
Optional<User> findBySendEmail(Boolean sendEmail);
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.models.Accept;
import br.com.treinaweb.twjobs.core.models.Vessel;
import jakarta.persistence.EntityManager;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class VesselCustomRepository {
private final EntityManager em;
public VesselCustomRepository(EntityManager em) {
this.em = em;
}
// id
// imo
// status
// nome
public List<Vessel> vesselsCustom(Long id, Long imo, String categoria, String nome){
String query = "select A from Vessel as A";
String condicao = " where ";
if(id!=null){
query += condicao + "A.id = :id";
condicao = " and ";
}
if(imo!=null){
query += condicao + "A.imo = :imo";
condicao = " and ";
}
if(categoria!=null){
query += condicao + "A.categoria = :categoria";
condicao = " and ";
}
if(nome!=null){
query += condicao + "A.nome LIKE :nome";
condicao = " and ";
}
var q = em.createQuery(query, Vessel.class);
if(id!=null){
q.setParameter("id", id);
}
if(imo!=null){
q.setParameter("imo", imo);
}
if(categoria!=null){
q.setParameter("categoria", categoria);
}
if(nome!=null){
q.setParameter("nome", "%"+nome+"%");
}
return q.getResultList();
}
}
package br.com.treinaweb.twjobs.core.repositories;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselResponse;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.models.Vessel;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import javax.swing.text.html.Option;
import java.util.List;
import java.util.Optional;
public interface VesselRepository extends JpaRepository<Vessel, Long> {
List<Vessel> findByNome(String nome);
List<Vessel> findByNomeContaining(String nome);
Optional<Vessel> findByImo(Long imo);
Optional<Vessel> findByImoAndUserId(Long imo, Long userId);
// Vessel findByImo(Long imo);
boolean existsByImo(Long imo);
boolean existsByImoAndIdNot(Long imo, Long id);
Page<Vessel> findAllByUser(Optional<User> user, Pageable pageable);
Page<Vessel> findAllByUserId(Pageable pageable, Long userId);
Page<Vessel> findByUserId(Pageable pageable, Long userId);
@Query("SELECT COUNT(u) FROM Vessel u")
Long countAllVessels();
// Vessel findAllByUser(User user);
// List<Vessel> findAll();
}
package br.com.treinaweb.twjobs.core.service;
import br.com.treinaweb.twjobs.api.accepts.assemblers.AcceptAssembler;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptRequest;
import br.com.treinaweb.twjobs.api.accepts.dtos.AcceptResponse;
import br.com.treinaweb.twjobs.api.accepts.mappers.AcceptMapper;
import br.com.treinaweb.twjobs.api.file.FileManagerController;
import br.com.treinaweb.twjobs.api.vessels.dtos.VesselRequest;
import br.com.treinaweb.twjobs.core.enums.EmailActivation;
import br.com.treinaweb.twjobs.core.enums.VeriStatus;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.exceptions.VesselNotFoundException;
import br.com.treinaweb.twjobs.core.models.*;
import br.com.treinaweb.twjobs.core.repositories.*;
import br.com.treinaweb.twjobs.core.services.auth.SecurityService;
//import jakarta.mail.Message;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.EntityModel;
//import org.springframework.mail.SimpleMailMessage;
//import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.HashMap;
import java.util.Map;
@AllArgsConstructor
@Service
public class CadastroAcceptService {
private final AcceptMapper acceptMapper;
private final AcceptAssembler acceptAssembler;
private final AcceptRepository acceptRepository;
private final SecurityService securityService;
private final PagedResourcesAssembler<AcceptResponse> pagedResourcesAssembler;
private final VesselRepository vesselRepository;
private final BercoRepository bercoRepository;
private final BlackListRepository blackListRepository;
private final FileManagerController fileManagerController;
private final EmailSendRepository emailSendRepository;
private final UserRepository userRepository;
@Autowired
private ObjectMapper mapper;
@Autowired
private EmailService emailService;
@Transactional
public EntityModel<AcceptResponse> salvar(String acceptRequestForm, MultipartFile foto, String destinatario) throws JsonProcessingException {
//verifica extensao
String filename = foto.getOriginalFilename();
String extension = null;
int dotIndex = filename.lastIndexOf(".");
if (dotIndex >= 0) {
extension = filename.substring(dotIndex + 1);
}
String[] extensions = {"txt", "zip", "pdf"};
Boolean verifica = false;
if(extension!=null) {
for(String i : extensions){
if(i.equals(extension) ) {
verifica =true;
break;
}
}
if(!verifica){
throw new NegocioException(extension);
}
}
// destinatario = String.valueOf(emailSendRepository.findByStatus(EmailActivation.enable));
//if you are using optional and want to get or set an attribute, you must use the "get()" before
destinatario = String.valueOf(userRepository.findBySendEmail(Boolean.TRUE).get().getEmail());
AcceptRequest acceptRequest = mapper.readValue(acceptRequestForm, AcceptRequest.class);
User user = securityService.getCurrentUser();
Long userId = user.getId();
var accept = acceptMapper.toAccept(acceptRequest);
accept.setUser(user);
if(foto!=null) {
accept.setPath(foto.getOriginalFilename());
fileManagerController.uploadFile(foto);
}
// """
// Procura navio por imo e userId.
// """
// Vessel vessel = vesselRepository.findByImoAndUserId(accept.getImo(), userId)
// .orElseThrow(VesselNotFoundException::new);
Vessel vessel = vesselRepository.findByImo(accept.getImo())
.orElseThrow(VesselNotFoundException::new);
// if(vessel.getCategoria()==null&&accept.getCategoria()!=null) {
// vessel.setCategoria(accept.getCategoria());
// vesselRepository.save(vessel);
// }
// """Setando as datas de alteração"""
accept.setVessel(vessel);
accept.setDataAccept(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
accept.setData_create(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
accept.setData_update(String.valueOf(LocalDate.now()));
accept.setTime_accept(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
accept.setTime_create(String.valueOf(LocalDate.now()+" "+ LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
accept.setTime_update(String.valueOf(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))));
// """ Inutilizado por enquanto
// Accept lastAccepted = acceptRepository.findTop1ByImoOrderByIdDesc(vessel.getImo());
List<Berco> bercos = bercoRepository.findAll();
List<Berco> bercosCompativeis = new ArrayList<>();
// CHECA SE TÁ NA BLACKLIST
boolean blackListed = blackListRepository.existsByImo(accept.getImo());
// ~~~ PLANO DE AMARRACAO PORTO(BASEADO NAS REUNIOES)
for (Berco berco : bercos) {
// if(Objects.equals(vessel.getCategoria(), berco.getCategoria())) {
// if ((vessel.getLoa()<=berco.getLoa_max())&&(acceptRequest.getCalado_entrada()<=berco.getCalado_max())&&(acceptRequest.getCalado_saida()<=berco.getCalado_max())&&(vessel.getDwt()<=berco.getDwt())
//// TESTAR SE TÁ FUNCIONANDO ESSA CHECAGEM DA BLACKLIST
// &&(!blackListed)
// ) {
// bercosCompativeis.add(berco);
// }
// }
if(Objects.equals(accept.getCategoria(), berco.getCategoria())) {
if ((accept.getLoa()<=berco.getLoa_max())&&(accept.getCalado_entrada()<=berco.getCalado_max())&&(accept.getCalado_saida()<=berco.getCalado_max())&&(accept.getDwt()<=berco.getDwt())
// TESTAR SE TÁ FUNCIONANDO ESSA CHECAGEM DA BLACKLIST
&&(!blackListed)
) {
bercosCompativeis.add(berco);
}
}
}
Accept lastAccept = acceptRepository.findFirstByOrderByDataAcceptDesc();
var lastAcceptId = lastAccept.getId();
var currentAcceptId = lastAcceptId +1;
if (!bercosCompativeis.isEmpty()) {
accept.setBercos(bercosCompativeis);
// accept.setStatus(VeriStatus.valueOf("Y"));
accept.setStatus("Y");
} else {
// id, imo, user, status, obs, data de criacao, local hospedagem + URIs
String msg;
if(blackListed) {
msg = "ID DO ACEITE: "+currentAcceptId+"\n"+
"IMO DO NAVIO: "+accept.getImo()+"\n"+
"CAUSA IDENTIFICADA(SISTEMA): Navio problemático, está na BLACK LIST!"+"\n"+
"STATUS INPUTADO PARA O ACEITE(SISTEMA): Em processamento"+"\n"+
"OBS DO USUÁRIO: "+accept.getObs()+"\n"+
"DATA CRIAÇÃO DO REGISTRO DE ACEITE: "+accept.getData_create()+"\n"+
"DADOS DO USUÁRIO: "+"ID: "+user.getId()+" E-MAIL: "+user.getEmail()+" NOME: "+user.getName()+" PAPÉL: "+user.getRole();
} else {
msg = "ID DO ACEITE: "+currentAcceptId+"\n"+
"IMO DO NAVIO: "+accept.getImo()+"\n"+
"CAUSA IDENTIFICADA(SISTEMA): Navio problemático, de acordo com categoria, loa, dwt e calados cadastrados, nenhum berço o comporta!"+"\n"+
"STATUS INPUTADO PARA O ACEITE(SISTEMA): Em processamento"+"\n"+
"OBS DO USUÁRIO: "+accept.getObs()+"\n"+
"DATA CRIAÇÃO DO REGISTRO DE ACEITE: "+accept.getData_create()+"\n"+
"DADOS DO USUÁRIO: "+"ID: "+user.getId()+" E-MAIL: "+user.getEmail()+" NOME: "+user.getName()+" PAPEL: "+user.getRole();
}
emailService.enviarEmailTexto(destinatario, "Aceite de Navio - BLOQUEADO", msg);
// accept.setStatus(VeriStatus.valueOf("N"));
accept.setStatus("N");
// throw new NegocioException("Nenhum berço compatível.");
}
accept = acceptRepository.save(accept);
var acceptResponse = acceptMapper.toAcceptResponse(accept);
return acceptAssembler.toModel(acceptResponse);
}
// ~~ ~~ ~~ COLOCAR DENTRO DE SAVE, CASO PRECISE AUTO-ALIMENTAR VESSEL COM OS DADOS DE ACCEPT
// @Transactional
// public EntityModel<AcceptResponse> saveAcceptOrUpdatadeVesselAlso(@Valid @RequestParam(name="AcceptRequestForm") String acceptRequestForm) {
//
//
//
//
// Accept savedAccept = acceptRepository.save(accept);
//
// // Atualiza os campos de Vessel, se necessário
// Vessel vessel = savedAccept.getVessel();
// if (vessel != null) {
// boolean updated = false;
//
// // Verifica e atualiza os campos comuns
// if (accept.getCommonField1() != null &&
// !accept.getCommonField1().equals(vessel.getCommonField1())) {
// vessel.setCommonField1(accept.getCommonField1());
// updated = true;
// }
//
// if (accept.getCommonField2() != null &&
// !accept.getCommonField2().equals(vessel.getCommonField2())) {
// vessel.setCommonField2(accept.getCommonField2());
// updated = true;
// }
//
// // Salva as alterações em Vessel, se houver
// if (updated) {
// vesselRepository.save(vessel);
// }
// }
//
// return savedAccept;
//
//
// }
// ESTATÍSTICA ACEITO, NEGADO, EM ANÁLISE
public Map<String, Long> getStatusStatistics() {
// Obtem os resultados agrupados diretamente do banco
List<Object[]> results = acceptRepository.countByStatus();
// Mapa para armazenar a estatística traduzida
Map<String, Long> statistics = new HashMap<>();
for (Object[] result : results) {
String statusCode = (String) result[0]; // Código de status ("1", "2", "3")
Long count = (Long) result[1]; // Contagem de registros
// Traduzir o status code para o rótulo correspondente
String statusLabel = mapStatusCodeToLabel(statusCode);
statistics.put(statusLabel, count);
}
return statistics;
}
/**
* Traduz os códigos de status do banco para rótulos legíveis.
*
* @param code Código de status (String)
* @return Rótulo legível (String)
*/
private String mapStatusCodeToLabel(String code) {
switch (code) {
case "1":
return "aceito";
case "2":
return "negado";
case "3":
return "em análise";
default:
return "desconhecido";
}
}
// Json de getStatusStatistics()
//{
// "aceito": 10,
// "negado": 5,
// "em análise": 8
//}
}
// ~~~ BACKUPS(IMPORTANTE)
// PLANO DE AMARRACAO PORTO(BASEADO NAS REUNIOES)
//
// for (Berco berco : bercos) {
//
//// ~ FALTA A VERIFICACAO DAS CATEGORIAS
// if ((vessel.getLoa()<=berco.getLoa_max())&&(acceptRequest.getCalado_entrada()<=berco.getCalado_max())&&(acceptRequest.getCalado_saida()<=berco.getCalado_max())&&(vessel.getDwt()<=berco.getDwt())) {
//
// bercosCompativeis.add(berco);
// }
// }
// for (Berco berco : bercos) {
//
//
// bercosCompativeis.add(berco);
//
//
// }
// for (Berco berco : bercos) {
// if ( vessel.getLoa()!=null
// &&berco.getLoa_max()!=null
// &&vessel.getDwt()!=null
// &&berco.getDwt()!=null
// &&vessel.getPontal()!=null
// &&berco.getCalado_max()!=null
// &&
// vessel.getLoa() <= berco.getLoa_max()
// && vessel.getDwt() <= berco.getDwt()
// && vessel.getPontal() <= berco.getCalado_max()) {
// bercosCompativeis.add(berco);
// }
// }
//
//
// // Define status e berço com base nas verificações
// if (!bercosCompativeis.isEmpty()) {
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(bercosCompativeis);
// } else {
//// Esse status representa que necessita-se de averiguação
// accept.setStatus(VeriStatus.valueOf("N"));
// throw new NegocioException("Nenhum berço compatível.");
// }
// PLANO DE AMARRACAO EM VIGENCIA DO SISTEMA
//
// for (Berco berco : bercos) {
// if (vessel.getLoa() <= berco.getLoa_max()
// && vessel.getDwt() <= berco.getDwt()
// ) {
// bercosCompativeis.add(berco);
// }
// }
//
//
// if (!bercosCompativeis.isEmpty()) {
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(bercosCompativeis);
// } else {
// accept.setStatus(VeriStatus.valueOf("N"));
// throw new NegocioException("Nenhum berço compatível.");
// }
// if ((vessel.getLoa()!=0&vessel.getDwt()!=0)) {
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(List.of(bercos.get(0)));
// }
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(List.of(bercos.get(0)));
//// """ Berços 99, 100, 101, 102, 103, 104 e 105:
// if(
// (vessel.getLoa()<150&vessel.getDwt()<20.000)
// || ((vessel.getLoa()>150&vessel.getLoa()<190)
// &(vessel.getDwt()>20.000&vessel.getDwt()<40.000))
// || (vessel.getLoa()>190&vessel.getDwt()>40.000)
// ) {
//
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(List.of(bercos.get(0)));
//
//
// }
//
//
//// """ Berços 106 e 108:
// else if(
// (vessel.getLoa()<190&vessel.getDwt()<40.000)
// || (vessel.getLoa()>190&vessel.getDwt()>20.000)
// ) {
//
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(List.of(bercos.get(1)));
//
//
// }
//
//
//// """ GLP:
// else if(
// (vessel.getCategoria()=="2"&vessel.getLoa()<100&vessel.getDwt()<10.000)
// || (vessel.getCategoria()=="2"&vessel.getLoa()>100&vessel.getDwt()>10.000)
// ) {
//
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(List.of(bercos.get(2)));
//
//
//// """ CONTAINERS:
// } else if(
// (vessel.getLoa()<150&vessel.getDwt()<20.000)
// || ((vessel.getLoa()>150&vessel.getLoa()<180)
// &(vessel.getDwt()>20.000&vessel.getDwt()<40.000))
// || (vessel.getLoa()>180&vessel.getDwt()>40.000)
// ) {
//
// throw new NegocioException("Nenhum container cadastrado.");
//
//
// }
//
//
//
//
// else {
//
//
// throw new NegocioException("Nenhum berço compatível.");
//
//
// }
// if(
// (vessel.getLoa()>150&vessel.getDwt()>20.000)
// ) {
// accept.setStatus(VeriStatus.valueOf("Y"));
// accept.setBercos(List.of(bercos.get(0),bercos.get(1)));
//
//
// }
// accept.setStatus(VeriStatus.valueOf("N"));
\ No newline at end of file
package br.com.treinaweb.twjobs.core.service;
public class CadastroVesselService {
}
package br.com.treinaweb.twjobs.core.service;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class EmailService {
@Autowired
private JavaMailSender javaMailSender;
@Value("$spring.mail.username")
private String remetente;
@Async
public String enviarEmailTexto(String destinatario, String assunto, String mensagem){
// throw new NegocioException("Teste.");
try {
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setFrom(remetente);
simpleMailMessage.setTo(destinatario);
simpleMailMessage.setSubject(assunto);
simpleMailMessage.setText(mensagem);
javaMailSender.send(simpleMailMessage);
return "Email enviado";
} catch(Exception e){
return "Erro ao tentar enviar e-mail" + e.getLocalizedMessage();
}
}
}
package br.com.treinaweb.twjobs.core.service;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@AllArgsConstructor
@Service
public class PersonalizedSearch {
// Accept
// BlackList
// Berco
// Vessel
// User
}
package br.com.treinaweb.twjobs.core.service;
import br.com.treinaweb.twjobs.core.repositories.*;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class StatisticsService {
private final VesselRepository vesselRepository;
private final AcceptRepository acceptRepository;
private final UserRepository userRepository;
private final BlackListRepository blackListRepository;
private final BercoRepository bercosRepository;
public StatisticsService(VesselRepository vesselRepository,
AcceptRepository acceptRepository,
UserRepository userRepository,
BlackListRepository blackListRepository,
BercoRepository bercosRepository) {
this.vesselRepository = vesselRepository;
this.acceptRepository = acceptRepository;
this.userRepository = userRepository;
this.blackListRepository = blackListRepository;
this.bercosRepository = bercosRepository;
}
public Map<String, Object> getStatistics() {
Map<String, Object> statistics = new HashMap<>();
// Contagem dos status
List<Object[]> statusCounts = acceptRepository.countByStatus();
Map<String, Long> statusMap = statusCounts.stream()
.collect(Collectors.toMap(
result -> (String) result[0],
result -> (Long) result[1]
));
// Contagem geral de entidades
statistics.put("statusCounts", statusMap);
statistics.put("totalVessels", vesselRepository.countAllVessels());
statistics.put("totalAccepts", acceptRepository.countAllAccepts());
statistics.put("totalUsers", userRepository.countAllUsers());
statistics.put("totalBlackLists", blackListRepository.countAllBlackLists());
statistics.put("totalBercos", bercosRepository.countAllBercos());
return statistics;
}
}
//@Transactional : se der algum erro toda a operação é cancelada
package br.com.treinaweb.twjobs.core.services;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.models.Navio;
import br.com.treinaweb.twjobs.core.repositories.NavioRepository;
import jakarta.transaction.Transactional;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
//Gerenciar o CRUD simples
@AllArgsConstructor
@Service
public class CadastroNavioService {
NavioRepository navioRepository;
@Transactional
public Navio salvar(Navio navio) {
boolean imo_existe = navioRepository.findByImo(navio.getImo()).filter(n ->!n.equals(navio)).isPresent();
if(imo_existe){
throw new NegocioException("Já existe navio cadastrado com esse IMO.");
}
// if(navio.getImo() != 34) {
// throw new NegocioException("O IMO não segue o padrão");
// }
return navioRepository.save(navio);
}
}
package br.com.treinaweb.twjobs.core.services;
import br.com.treinaweb.twjobs.core.exceptions.NegocioException;
import br.com.treinaweb.twjobs.core.models.Vessel;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import jakarta.transaction.Transactional;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@AllArgsConstructor
@Service
public class CadastroVesselService {
VesselRepository vesselRepository;
@Transactional
public Vessel salvar(Vessel vessel) {
boolean imo_existe = vesselRepository.findByImo(vessel.getImo()).filter(n ->!n.equals(vessel)).isPresent();
if(imo_existe){
throw new NegocioException("Já existe navio cadastrado com esse IMO.");
}
return vesselRepository.save(vessel);
}
}
package br.com.treinaweb.twjobs.core.services.auth;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import br.com.treinaweb.twjobs.core.models.User;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public class AuthenticatedUser implements UserDetails {
private final User user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return AuthorityUtils.createAuthorityList(user.getRole().name());
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getEmail();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
package br.com.treinaweb.twjobs.core.services.auth;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import br.com.treinaweb.twjobs.core.repositories.UserRepository;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class AuthenticationService implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findByEmail(username)
.map(AuthenticatedUser::new)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
}
}
package br.com.treinaweb.twjobs.core.services.auth;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import br.com.treinaweb.twjobs.core.models.User;
import br.com.treinaweb.twjobs.core.repositories.JobRepository;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class SecurityService {
private final JobRepository jobRepository;
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
public boolean isAuthenticated() {
var authentication = getAuthentication();
return authentication != null
&& !(authentication instanceof AnonymousAuthenticationToken)
&& authentication.isAuthenticated();
}
public User getCurrentUser() {
if (!isAuthenticated()) {
throw new InsufficientAuthenticationException("Unauthenticated");
}
var authentication = (AuthenticatedUser) getAuthentication().getPrincipal();
return authentication.getUser();
}
public boolean isOwner(String companyEmail, Long jobId) {
return jobRepository.existsByCompanyEmailAndId(companyEmail, jobId);
}
}
package br.com.treinaweb.twjobs.core.services.http;
import java.util.Optional;
public interface HttpService {
<T> Optional<T> getPathVariable(String name, Class<T> type);
}
package br.com.treinaweb.twjobs.core.services.http;
import java.util.Map;
import java.util.Optional;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerMapping;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class HttpServiceImpl implements HttpService {
private final ObjectMapper objectMapper;
private final HttpServletRequest request;
@Override
public <T> Optional<T> getPathVariable(String name, Class<T> type) {
var attrs = request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
var pathVariables = objectMapper.convertValue(
attrs,
new TypeReference<Map<String, String>>() {}
);
var value = pathVariables.getOrDefault(name, null);
if (value == null) {
return Optional.empty();
}
return Optional.of(objectMapper.convertValue(value, type));
}
}
package br.com.treinaweb.twjobs.core.services.jwt;
import java.time.Instant;
import java.util.Date;
import br.com.treinaweb.twjobs.core.enums.Role;
import org.springframework.stereotype.Service;
import br.com.treinaweb.twjobs.config.JwtConfigProperties;
import br.com.treinaweb.twjobs.core.exceptions.JwtServiceException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class JjwtJwtService implements JwtService {
private final JwtConfigProperties configProperties;
@Override
public String generateAccessToken(String sub, Role role) {
return generateToken(
sub,
role,
configProperties.getAccessSecret(),
configProperties.getAccessExpiresIn()
);
}
@Override
public String getSubFromAccessToken(String token) {
return getSubFromToken(token, configProperties.getAccessSecret());
}
@Override
public String generateRefreshToken(String sub, Role role) {
return generateToken(
sub,
role,
configProperties.getRefreshSecret(),
configProperties.getRefreshExpiresIn()
);
}
@Override
public String getSubFromRefreshToken(String token) {
return getSubFromToken(token, configProperties.getRefreshSecret());
}
private String generateToken(String sub, Role role, String secret, Long expiresIn) {
var now = Instant.now();
var expiration = now.plusSeconds(expiresIn);
var key = Keys.hmacShaKeyFor(secret.getBytes());
return Jwts.builder()
.setSubject(sub)
.claim("role", role.name()) // Adicionando a role ao claim do token
.setIssuedAt(Date.from(now))
.setExpiration(Date.from(expiration))
.signWith(key)
.compact();
}
private String getSubFromToken(String token, String secret) {
var key = Keys.hmacShaKeyFor(secret.getBytes());
try {
Claims claims = Jwts.parser()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
return claims.getSubject();
} catch (JwtException e) {
throw new JwtServiceException("Erro ao decodificar o token JWT: " + e.getMessage());
}
}
}
\ No newline at end of file
package br.com.treinaweb.twjobs.core.services.jwt;
import br.com.treinaweb.twjobs.core.enums.Role;
public interface JwtService {
String generateAccessToken(String sub, Role role);
String getSubFromAccessToken(String token);
String generateRefreshToken(String sub, Role role);
String getSubFromRefreshToken(String token);
}
\ No newline at end of file
package br.com.treinaweb.twjobs.core.validators;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = BercoNameIsUniqueValidator.class)
public @interface BercoNameIsUnique {
String message() default "this ${validatedValue} berco name is already in use";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
package br.com.treinaweb.twjobs.core.validators;
import br.com.treinaweb.twjobs.core.repositories.BercoRepository;
import br.com.treinaweb.twjobs.core.services.http.HttpService;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class BercoNameIsUniqueValidator implements ConstraintValidator<BercoNameIsUnique, Long> {
private final HttpService httpService;
private final BercoRepository bercoRepository;
// @Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
var id = httpService.getPathVariable("id", Long.class);
if (id.isEmpty()) {
return !bercoRepository.existsByNome(value);
}
return !bercoRepository.existsByNomeAndIdNot(value, id.get());
}
/* @Override
public boolean isValid(Long aLong, ConstraintValidatorContext constraintValidatorContext) {
return false;
}*/
}
package br.com.treinaweb.twjobs.core.validators;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SkillNameIsUniqueValidator.class)
public @interface SkillNameIsUnique {
String message() default "this ${validatedValue} skill name is already in use";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
package br.com.treinaweb.twjobs.core.validators;
import org.springframework.stereotype.Component;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import br.com.treinaweb.twjobs.core.services.http.HttpService;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
public class SkillNameIsUniqueValidator implements ConstraintValidator<SkillNameIsUnique, String> {
private final HttpService httpService;
private final SkillRepository skillRepository;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
var id = httpService.getPathVariable("id", Long.class);
if (id.isEmpty()) {
return !skillRepository.existsByName(value);
}
return !skillRepository.existsByNameAndIdNot(value, id.get());
}
}
package br.com.treinaweb.twjobs.core.validators;
public interface ValidationGroups {
public interface ClienteId{
}
public interface NavioId{
}
public interface VesselId{
}
}
package br.com.treinaweb.twjobs.core.validators;
import br.com.treinaweb.twjobs.core.models.Vessel;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = VesselImoisUniqueValidator.class)
public @interface VesselImoIsUnique {
String message() default "this ${validatedValue} vessel Imo is already in use";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
package br.com.treinaweb.twjobs.core.validators;
import br.com.treinaweb.twjobs.core.repositories.SkillRepository;
import br.com.treinaweb.twjobs.core.repositories.VesselRepository;
import br.com.treinaweb.twjobs.core.services.http.HttpService;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class VesselImoisUniqueValidator implements ConstraintValidator<VesselImoIsUnique, Long> {
private final HttpService httpService;
private final VesselRepository vesselRepository;
@Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
var id = httpService.getPathVariable("id", Long.class);
if (id.isEmpty() ) {
return !vesselRepository.existsByImo(value);
}
return !vesselRepository.existsByImoAndIdNot(value, id.get());
/* var imo = httpService.getPathVariable("imo", Long.class);
if (imo.isEmpty()) {
return !vesselRepository.existsByImo(value);
}
return !vesselRepository.existsByImoAndIdNot(value, imo.get());*/
}
}
{"properties": [
{
"name": "br.com.treinaweb.twjobs.jwt.accessSecret",
"type": "java.lang.String",
"description": "Chave secreta para geração do token de acesso"
},
{
"name": "br.com.treinaweb.twjobs.jwt.accessExpiresIn",
"type": "java.lang.Long",
"description": "Tempo de expiração em segundos do token de acesso"
},
{
"name": "br.com.treinaweb.twjobs.jwt.refreshSecret",
"type": "java.lang.String",
"description": "Chave secreta para geração do token de atualização"
},
{
"name": "br.com.treinaweb.twjobs.jwt.refreshExpiresIn",
"type": "java.lang.Long",
"description": "Tempo de expiração em segundos do token de atualização"
}
]}
\ No newline at end of file
# Datasource configuration
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
#Great
spring.datasource.url=jdbc:mysql://host.docker.internal:3306/porto?createDatabaseIfNotExist=true&serverTimezone=UTC
#spring.datasource.url=jdbc:mysql://localhost:3306/porto
spring.datasource.username=root
spring.datasource.password=root
#Alien
#spring.datasource.url=jdbc:mysql://localhost:3306/porto
#spring.datasource.url=jdbc:mysql://localhost:3306/portem
#Laps
#spring.datasource.url=jdbc:mysql://localhost:3306/twjobs
#spring.datasource.username=root
#spring.datasource.password=Pasq2024@
#spring.datasource.password=root
spring.servlet.multipart.max-file-size=2GB
spring.servlet.multipart.max-request-size=2GB
#Email
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=pauloacb2020@gmail.com
spring.mail.password=ehyn ryqu utgv ntjd
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
# JPA configuration
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.event.merge.entity_copy_observer=allow
# Hibernate configuration
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.format_sql=true
# Pagination configuration
spring.data.web.pageable.one-indexed-parameters=true
spring.data.web.pageable.default-page-size=2
#tamanho m�ximo de pagina��o pra todo sistema
spring.data.web.pageable.max-page-size=20
# spring.data.web.pageable.page-parameter=pagina
# spring.data.web.pageable.size-parameter=tamanho
br.com.treinaweb.twjobs.jwt.accessSecret=b9048bb98d808d82bf7250333035db0ea7ada419a53153ec550fcf3dd6d51b13
br.com.treinaweb.twjobs.jwt.accessExpiresIn=3600
br.com.treinaweb.twjobs.jwt.refreshSecret=5893d555ee0b886b14929d630c2027b912c104ca29295bf9fd126666baf5bff1
br.com.treinaweb.twjobs.jwt.refreshExpiresIn=7200
contato.disco.raiz = C:\\fotos-java
contato.disco.diretorio-fotos = contato-disco
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment