├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── LICENSE ├── README.md ├── data.js ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── spring │ │ └── tp │ │ ├── SpringDataProjectApplication.java │ │ ├── controllers │ │ ├── ArbitreController.java │ │ ├── EquipeController.java │ │ ├── JoueurController.java │ │ ├── MatcheController.java │ │ └── StadeController.java │ │ ├── entities │ │ ├── Arbitre.java │ │ ├── Equipe.java │ │ ├── Joueur.java │ │ ├── Matche.java │ │ └── Stade.java │ │ ├── repositories │ │ ├── ArbitreRepository.java │ │ ├── EquipeRepository.java │ │ ├── JoueurRepository.java │ │ ├── MatcheRepository.java │ │ └── StadeRepository.java │ │ └── services │ │ ├── ArbitreService.java │ │ ├── EquipeService.java │ │ ├── JoueurService.java │ │ ├── MatcheService.java │ │ └── StadeService.java └── resources │ └── application.properties └── test └── java └── spring └── tp └── SpringDataProjectApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/walidbosso/SpringBoot_Football_Matches/f9da3cbbd0fd2a7d95411bdbb3d722170e96517c/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Walid BOUSSOU 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![SpringBoot_Football_Matches](https://socialify.git.ci/walidbosso/SpringBoot_Football_Matches/image?description=1&font=Source%20Code%20Pro&forks=1&issues=1&language=1&name=1&owner=1&pattern=Formal%20Invitation&pulls=1&stargazers=1&theme=Auto) 2 | 3 | 4 |

5 | 6 | 7 |

8 |
9 | 10 | [![GitHub WidgetBox](https://github-widgetbox.vercel.app/api/profile?username=walidbosso&data=followers,repositories,stars,commits&theme=nautilus)](https://github.com/walidbosso/SpringBoot_Football_Matches) 11 | 12 | 13 |

14 | 15 | 16 |

17 | 18 | 19 | 20 | 21 | 22 | 23 | # Football Match Simulation 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | This project is a Spring Boot application that simulates football matches. It utilizes Spring Web and Data with JPA, MySQL Driver, and Lombok to manage various components of football games, including teams, stadium, referee, and players. 32 | 33 | ## Topics 34 | 35 | - [MySQL](#mysql) 36 | - [Services](#services) 37 | - [Spring Boot](#spring-boot) 38 | - [Controller](#controller) 39 | - [Model](#model) 40 | - [Lombok](#lombok) 41 | - [Football Simulation](#football-simulation) 42 | - [STS (Spring Tool Suite)](#sts) 43 | - [PHPMyAdmin](#phpmyadmin) 44 | - [Spring Data JPA](#spring-data-jpa) 45 | - [Web Development](#web-development) 46 | - [Repositories](#repositories) 47 | - [Spring Web](#spring-web) 48 | - [Football Match](#football-match) 49 | - [MySQL Drivers](#mysql-drivers) 50 | 51 | ## Overview 52 | 53 | Academic project, Master's in Computer Science Engineering. 54 | 55 | ## Technologies Used 56 | 57 | - **Spring Boot:** Framework for building Java-based enterprise applications. 58 | - **MySQL:** Database management system used to store football-related data. 59 | - **Lombok:** Java library to reduce boilerplate code, making development cleaner and more concise. 60 | 61 | ## Development Environment 62 | 63 | - **Spring Tool Suite (STS):** An integrated development environment for building, testing, and deploying Spring applications. 64 | - **PHPMyAdmin:** Web-based tool for managing MySQL databases. 65 | 66 | ## Usage 67 | - Fork then Clone the repository. 68 | 69 | - Open it on STS IDE after instaling it, Maven will build the necessary tools, use `POSTMAN` for testing. 70 | 71 | - Contact me in [LinkedIn](https://www.linkedin.com/in/walidbosso) for questions. 72 | 73 |
74 | 75 |
76 | 77 | ---------------------- 78 | > >  
© *by Walid BOUSSOU*  🇲🇦 😄
  79 | ---------------------- 80 | 81 |
82 | 👏 Thanks for the support 83 | 84 | ## Stargazers 85 | 86 | 87 |
88 | 89 | [![Stargazers repo roster for @walidbosso/SpringBoot_Football_Matches](http://reporoster.com/stars/dark/walidbosso/SpringBoot_Football_Matches)](https://github.com/walidbosso/SpringBoot_Football_Matches/stargazers) 90 | 91 | 92 | 93 |
94 | 95 | ## Forkers 96 | 97 |
98 | 99 | [![Forkers repo roster for @walidbosso/SpringBoot_Football_Matches](http://reporoster.com/forks/dark/walidbosso/SpringBoot_Football_Matches)](https://github.com/walidbosso/SpringBoot_Football_Matches/network/members) 100 | 101 |
102 | 103 | ## Contributors 104 | 105 | 106 | 107 | 108 | 109 | 110 |

111 | 112 |
113 | 114 | ![GitHub last commit (by committer)](https://img.shields.io/github/last-commit/walidbosso/SpringBoot_Football_Matches?style=social) 115 | 116 |
117 |
118 | 119 | ![GitHub License](https://img.shields.io/github/license/walidbosso/SpringBoot_Football_Matches?style=social) 120 | 121 | 122 | 123 |
124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 𝚂𝚑𝚘𝚠 𝚜𝚘𝚖𝚎 💙 𝚋𝚢 𝚜𝚝𝚊𝚛𝚛𝚒𝚗𝚐 ⭐ 𝚝𝚑𝚎 𝚛𝚎𝚙𝚘𝚜𝚒𝚝𝚘𝚛𝚢! 138 | 139 |

140 | 141 | 142 |

Back to top

143 | -------------------------------------------------------------------------------- /data.js: -------------------------------------------------------------------------------- 1 | {'now':'1704504524147'} 2 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.2.0 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | # e.g. to debug Maven itself, use 32 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | # ---------------------------------------------------------------------------- 35 | 36 | if [ -z "$MAVEN_SKIP_RC" ] ; then 37 | 38 | if [ -f /usr/local/etc/mavenrc ] ; then 39 | . /usr/local/etc/mavenrc 40 | fi 41 | 42 | if [ -f /etc/mavenrc ] ; then 43 | . /etc/mavenrc 44 | fi 45 | 46 | if [ -f "$HOME/.mavenrc" ] ; then 47 | . "$HOME/.mavenrc" 48 | fi 49 | 50 | fi 51 | 52 | # OS specific support. $var _must_ be set to either true or false. 53 | cygwin=false; 54 | darwin=false; 55 | mingw=false 56 | case "$(uname)" in 57 | CYGWIN*) cygwin=true ;; 58 | MINGW*) mingw=true;; 59 | Darwin*) darwin=true 60 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 61 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 62 | if [ -z "$JAVA_HOME" ]; then 63 | if [ -x "/usr/libexec/java_home" ]; then 64 | JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME 65 | else 66 | JAVA_HOME="/Library/Java/Home"; export JAVA_HOME 67 | fi 68 | fi 69 | ;; 70 | esac 71 | 72 | if [ -z "$JAVA_HOME" ] ; then 73 | if [ -r /etc/gentoo-release ] ; then 74 | JAVA_HOME=$(java-config --jre-home) 75 | fi 76 | fi 77 | 78 | # For Cygwin, ensure paths are in UNIX format before anything is touched 79 | if $cygwin ; then 80 | [ -n "$JAVA_HOME" ] && 81 | JAVA_HOME=$(cygpath --unix "$JAVA_HOME") 82 | [ -n "$CLASSPATH" ] && 83 | CLASSPATH=$(cygpath --path --unix "$CLASSPATH") 84 | fi 85 | 86 | # For Mingw, ensure paths are in UNIX format before anything is touched 87 | if $mingw ; then 88 | [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && 89 | JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" 90 | fi 91 | 92 | if [ -z "$JAVA_HOME" ]; then 93 | javaExecutable="$(which javac)" 94 | if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then 95 | # readlink(1) is not available as standard on Solaris 10. 96 | readLink=$(which readlink) 97 | if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then 98 | if $darwin ; then 99 | javaHome="$(dirname "\"$javaExecutable\"")" 100 | javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" 101 | else 102 | javaExecutable="$(readlink -f "\"$javaExecutable\"")" 103 | fi 104 | javaHome="$(dirname "\"$javaExecutable\"")" 105 | javaHome=$(expr "$javaHome" : '\(.*\)/bin') 106 | JAVA_HOME="$javaHome" 107 | export JAVA_HOME 108 | fi 109 | fi 110 | fi 111 | 112 | if [ -z "$JAVACMD" ] ; then 113 | if [ -n "$JAVA_HOME" ] ; then 114 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 115 | # IBM's JDK on AIX uses strange locations for the executables 116 | JAVACMD="$JAVA_HOME/jre/sh/java" 117 | else 118 | JAVACMD="$JAVA_HOME/bin/java" 119 | fi 120 | else 121 | JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" 122 | fi 123 | fi 124 | 125 | if [ ! -x "$JAVACMD" ] ; then 126 | echo "Error: JAVA_HOME is not defined correctly." >&2 127 | echo " We cannot execute $JAVACMD" >&2 128 | exit 1 129 | fi 130 | 131 | if [ -z "$JAVA_HOME" ] ; then 132 | echo "Warning: JAVA_HOME environment variable is not set." 133 | fi 134 | 135 | # traverses directory structure from process work directory to filesystem root 136 | # first directory with .mvn subdirectory is considered project base directory 137 | find_maven_basedir() { 138 | if [ -z "$1" ] 139 | then 140 | echo "Path not specified to find_maven_basedir" 141 | return 1 142 | fi 143 | 144 | basedir="$1" 145 | wdir="$1" 146 | while [ "$wdir" != '/' ] ; do 147 | if [ -d "$wdir"/.mvn ] ; then 148 | basedir=$wdir 149 | break 150 | fi 151 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 152 | if [ -d "${wdir}" ]; then 153 | wdir=$(cd "$wdir/.." || exit 1; pwd) 154 | fi 155 | # end of workaround 156 | done 157 | printf '%s' "$(cd "$basedir" || exit 1; pwd)" 158 | } 159 | 160 | # concatenates all lines of a file 161 | concat_lines() { 162 | if [ -f "$1" ]; then 163 | # Remove \r in case we run on Windows within Git Bash 164 | # and check out the repository with auto CRLF management 165 | # enabled. Otherwise, we may read lines that are delimited with 166 | # \r\n and produce $'-Xarg\r' rather than -Xarg due to word 167 | # splitting rules. 168 | tr -s '\r\n' ' ' < "$1" 169 | fi 170 | } 171 | 172 | log() { 173 | if [ "$MVNW_VERBOSE" = true ]; then 174 | printf '%s\n' "$1" 175 | fi 176 | } 177 | 178 | BASE_DIR=$(find_maven_basedir "$(dirname "$0")") 179 | if [ -z "$BASE_DIR" ]; then 180 | exit 1; 181 | fi 182 | 183 | MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR 184 | log "$MAVEN_PROJECTBASEDIR" 185 | 186 | ########################################################################################## 187 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 188 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 189 | ########################################################################################## 190 | wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" 191 | if [ -r "$wrapperJarPath" ]; then 192 | log "Found $wrapperJarPath" 193 | else 194 | log "Couldn't find $wrapperJarPath, downloading it ..." 195 | 196 | if [ -n "$MVNW_REPOURL" ]; then 197 | wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 198 | else 199 | wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 200 | fi 201 | while IFS="=" read -r key value; do 202 | # 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 '=' ) 203 | safeValue=$(echo "$value" | tr -d '\r') 204 | case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; 205 | esac 206 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 207 | log "Downloading from: $wrapperUrl" 208 | 209 | if $cygwin; then 210 | wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") 211 | fi 212 | 213 | if command -v wget > /dev/null; then 214 | log "Found wget ... using wget" 215 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" 216 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 217 | wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 218 | else 219 | wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 220 | fi 221 | elif command -v curl > /dev/null; then 222 | log "Found curl ... using curl" 223 | [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" 224 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 225 | curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 226 | else 227 | curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" 228 | fi 229 | else 230 | log "Falling back to using Java to download" 231 | javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" 232 | javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" 233 | # For Cygwin, switch paths to Windows format before running javac 234 | if $cygwin; then 235 | javaSource=$(cygpath --path --windows "$javaSource") 236 | javaClass=$(cygpath --path --windows "$javaClass") 237 | fi 238 | if [ -e "$javaSource" ]; then 239 | if [ ! -e "$javaClass" ]; then 240 | log " - Compiling MavenWrapperDownloader.java ..." 241 | ("$JAVA_HOME/bin/javac" "$javaSource") 242 | fi 243 | if [ -e "$javaClass" ]; then 244 | log " - Running MavenWrapperDownloader.java ..." 245 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" 246 | fi 247 | fi 248 | fi 249 | fi 250 | ########################################################################################## 251 | # End of extension 252 | ########################################################################################## 253 | 254 | # If specified, validate the SHA-256 sum of the Maven wrapper jar file 255 | wrapperSha256Sum="" 256 | while IFS="=" read -r key value; do 257 | case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; 258 | esac 259 | done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" 260 | if [ -n "$wrapperSha256Sum" ]; then 261 | wrapperSha256Result=false 262 | if command -v sha256sum > /dev/null; then 263 | if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then 264 | wrapperSha256Result=true 265 | fi 266 | elif command -v shasum > /dev/null; then 267 | if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then 268 | wrapperSha256Result=true 269 | fi 270 | else 271 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." 272 | echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." 273 | exit 1 274 | fi 275 | if [ $wrapperSha256Result = false ]; then 276 | echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 277 | echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 278 | echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 279 | exit 1 280 | fi 281 | fi 282 | 283 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 284 | 285 | # For Cygwin, switch paths to Windows format before running java 286 | if $cygwin; then 287 | [ -n "$JAVA_HOME" ] && 288 | JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") 289 | [ -n "$CLASSPATH" ] && 290 | CLASSPATH=$(cygpath --path --windows "$CLASSPATH") 291 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 292 | MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") 293 | fi 294 | 295 | # Provide a "standardized" way to retrieve the CLI args that will 296 | # work with both Windows and non-Windows executions. 297 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" 298 | export MAVEN_CMD_LINE_ARGS 299 | 300 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 301 | 302 | # shellcheck disable=SC2086 # safe args 303 | exec "$JAVACMD" \ 304 | $MAVEN_OPTS \ 305 | $MAVEN_DEBUG_OPTS \ 306 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 307 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 308 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 309 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Apache Maven Wrapper startup batch script, version 3.2.0 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 28 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 29 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 30 | @REM e.g. to debug Maven itself, use 31 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 32 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 33 | @REM ---------------------------------------------------------------------------- 34 | 35 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 36 | @echo off 37 | @REM set title of command window 38 | title %0 39 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 40 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 41 | 42 | @REM set %HOME% to equivalent of $HOME 43 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 44 | 45 | @REM Execute a user defined script before this one 46 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 47 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 48 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 49 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 50 | :skipRcPre 51 | 52 | @setlocal 53 | 54 | set ERROR_CODE=0 55 | 56 | @REM To isolate internal variables from possible post scripts, we use another setlocal 57 | @setlocal 58 | 59 | @REM ==== START VALIDATION ==== 60 | if not "%JAVA_HOME%" == "" goto OkJHome 61 | 62 | echo. 63 | echo Error: JAVA_HOME not found in your environment. >&2 64 | echo Please set the JAVA_HOME variable in your environment to match the >&2 65 | echo location of your Java installation. >&2 66 | echo. 67 | goto error 68 | 69 | :OkJHome 70 | if exist "%JAVA_HOME%\bin\java.exe" goto init 71 | 72 | echo. 73 | echo Error: JAVA_HOME is set to an invalid directory. >&2 74 | echo JAVA_HOME = "%JAVA_HOME%" >&2 75 | echo Please set the JAVA_HOME variable in your environment to match the >&2 76 | echo location of your Java installation. >&2 77 | echo. 78 | goto error 79 | 80 | @REM ==== END VALIDATION ==== 81 | 82 | :init 83 | 84 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 85 | @REM Fallback to current working directory if not found. 86 | 87 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 88 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 89 | 90 | set EXEC_DIR=%CD% 91 | set WDIR=%EXEC_DIR% 92 | :findBaseDir 93 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 94 | cd .. 95 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 96 | set WDIR=%CD% 97 | goto findBaseDir 98 | 99 | :baseDirFound 100 | set MAVEN_PROJECTBASEDIR=%WDIR% 101 | cd "%EXEC_DIR%" 102 | goto endDetectBaseDir 103 | 104 | :baseDirNotFound 105 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 106 | cd "%EXEC_DIR%" 107 | 108 | :endDetectBaseDir 109 | 110 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 111 | 112 | @setlocal EnableExtensions EnableDelayedExpansion 113 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 114 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 115 | 116 | :endReadAdditionalConfig 117 | 118 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 123 | 124 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 125 | IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B 126 | ) 127 | 128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 130 | if exist %WRAPPER_JAR% ( 131 | if "%MVNW_VERBOSE%" == "true" ( 132 | echo Found %WRAPPER_JAR% 133 | ) 134 | ) else ( 135 | if not "%MVNW_REPOURL%" == "" ( 136 | SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" 137 | ) 138 | if "%MVNW_VERBOSE%" == "true" ( 139 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 140 | echo Downloading from: %WRAPPER_URL% 141 | ) 142 | 143 | powershell -Command "&{"^ 144 | "$webclient = new-object System.Net.WebClient;"^ 145 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 146 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 147 | "}"^ 148 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ 149 | "}" 150 | if "%MVNW_VERBOSE%" == "true" ( 151 | echo Finished downloading %WRAPPER_JAR% 152 | ) 153 | ) 154 | @REM End of extension 155 | 156 | @REM If specified, validate the SHA-256 sum of the Maven wrapper jar file 157 | SET WRAPPER_SHA_256_SUM="" 158 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 159 | IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B 160 | ) 161 | IF NOT %WRAPPER_SHA_256_SUM%=="" ( 162 | powershell -Command "&{"^ 163 | "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ 164 | "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ 165 | " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ 166 | " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ 167 | " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ 168 | " exit 1;"^ 169 | "}"^ 170 | "}" 171 | if ERRORLEVEL 1 goto error 172 | ) 173 | 174 | @REM Provide a "standardized" way to retrieve the CLI args that will 175 | @REM work with both Windows and non-Windows executions. 176 | set MAVEN_CMD_LINE_ARGS=%* 177 | 178 | %MAVEN_JAVA_EXE% ^ 179 | %JVM_CONFIG_MAVEN_PROPS% ^ 180 | %MAVEN_OPTS% ^ 181 | %MAVEN_DEBUG_OPTS% ^ 182 | -classpath %WRAPPER_JAR% ^ 183 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 184 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 185 | if ERRORLEVEL 1 goto error 186 | goto end 187 | 188 | :error 189 | set ERROR_CODE=1 190 | 191 | :end 192 | @endlocal & set ERROR_CODE=%ERROR_CODE% 193 | 194 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 195 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 196 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 197 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 198 | :skipRcPost 199 | 200 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 201 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 202 | 203 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 204 | 205 | cmd /C exit /B %ERROR_CODE% 206 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.1.5 9 | 10 | 11 | spring.tp 12 | SpringDataProject 13 | 0.0.1-SNAPSHOT 14 | SpringDataProject 15 | Demo project for Spring Boot 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-devtools 32 | runtime 33 | true 34 | 35 | 36 | com.mysql 37 | mysql-connector-j 38 | runtime 39 | 40 | 41 | org.projectlombok 42 | lombok 43 | true 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | 60 | org.projectlombok 61 | lombok 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/SpringDataProjectApplication.java: -------------------------------------------------------------------------------- 1 | package spring.tp; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringDataProjectApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringDataProjectApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/controllers/ArbitreController.java: -------------------------------------------------------------------------------- 1 | package spring.tp.controllers; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.DeleteMapping; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.PutMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import spring.tp.entities.Arbitre; 15 | import spring.tp.entities.Matche; 16 | 17 | import spring.tp.services.ArbitreService; 18 | 19 | @RestController 20 | public class ArbitreController { 21 | 22 | @Autowired 23 | ArbitreService as; 24 | 25 | 26 | @PostMapping("arbitre") 27 | public Arbitre addArbitre(@RequestBody Arbitre g) { 28 | return as.addArbitre(g); 29 | } 30 | 31 | @PostMapping("arbitre/{id}/matche/{id2}") 32 | public Matche addMatcheToArbitre(@PathVariable Long id, @RequestBody Matche m, @PathVariable Long id2) { 33 | 34 | return as.addMatcheToArbitre(id, m, id2);} 35 | 36 | 37 | @GetMapping("arbitre") 38 | List getAllArbitres(){ 39 | return as.getAllArbitres(); 40 | } 41 | 42 | 43 | @GetMapping("arbitre/{id}") 44 | public Arbitre getArbitreById(@PathVariable Long id) { 45 | return as.getArbitreById(id); 46 | 47 | } 48 | 49 | @GetMapping("arbitre/{id}/matche") 50 | public List getMatcheByarbitreId(@PathVariable Long id) { 51 | 52 | return as.getMatcheByarbitreId(id); 53 | } 54 | 55 | @DeleteMapping("arbitre/{id}") 56 | public void deleteArbitre(@PathVariable Long id) { 57 | as.deleteArbitre(id); 58 | } 59 | 60 | @PutMapping("arbitre") 61 | public Arbitre updateArbitre(@RequestBody Arbitre s) { 62 | return as.updateArbitre(s); 63 | } 64 | } 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/controllers/EquipeController.java: -------------------------------------------------------------------------------- 1 | package spring.tp.controllers; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.DeleteMapping; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.PutMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import spring.tp.entities.Joueur; 15 | import spring.tp.entities.Matche; 16 | import spring.tp.entities.Equipe; 17 | 18 | import spring.tp.services.EquipeService; 19 | 20 | @RestController 21 | public class EquipeController { 22 | 23 | @Autowired 24 | EquipeService es; 25 | 26 | @PostMapping("equipe") 27 | public Equipe addEquipe(@RequestBody Equipe e) { 28 | return es.addEquipe(e); 29 | } 30 | 31 | @GetMapping("equipe") 32 | List getAllEquipes(){ 33 | return es.getAllEquipes(); 34 | } 35 | 36 | @GetMapping("equipe/{id}") 37 | public Equipe getEquipeById(@PathVariable Long id) { 38 | return es.getEquipeById(id); 39 | } 40 | 41 | //we'll add player to equipe with id in url 42 | @PostMapping("equipe/{id}/joueur") 43 | public Joueur addJoueurToEquipe(@PathVariable Long id, @RequestBody Joueur m) { 44 | 45 | return es.addJoueurToEquipe(id, m); 46 | } 47 | 48 | @GetMapping("equipe/maroc") 49 | public List findByPays() { 50 | 51 | return es.findByPays(); 52 | } 53 | 54 | //show list of players that belongs to an equipe with id url 55 | @GetMapping("equipe/{id}/joueur") 56 | public List getJoueurByEquipeId(@PathVariable Long id) { 57 | return es.getJoueurByEquipeId(id); 58 | } 59 | 60 | //show list of players that belongs to an equipe with nom in url 61 | @GetMapping("equipe/nom/{nom}/joueur") 62 | public List getJoueurByEquipeNom(@PathVariable String nom) { 63 | 64 | return es.getJoueurByEquipeNom(nom); 65 | } 66 | 67 | @GetMapping("equipe/nom/{nom}/post/{post}") 68 | public List getJoueurByEquipeNomAndPost(@PathVariable String nom,@PathVariable String post) { 69 | 70 | 71 | return es.getJoueurByEquipeNomAndPost(nom, post); 72 | 73 | } 74 | 75 | //we'll add a match to an equipe, as an equipe1, match will save all infos of that equipe as an equipe1 76 | @PostMapping("equipe1/{id}/matche/{id2}") 77 | public Matche addMatcheToEquipe1(@PathVariable Long id, @RequestBody Matche m, @PathVariable Long id2) { 78 | return es.addMatcheToEquipe1(id, m, id2); 79 | } 80 | 81 | @PostMapping("equipe2/{id}/matche/{id2}") 82 | public Matche addMatcheToEquipe2(@PathVariable Long id, @RequestBody Matche m, @PathVariable Long id2) { 83 | return es.addMatcheToEquipe2(id, m, id2); 84 | } 85 | 86 | @GetMapping("equipe1/{id}/match") 87 | public List getMatchByEquipe1Id(@PathVariable Long id) { 88 | return es.getMatchByEquipe1Id(id); 89 | } 90 | 91 | @GetMapping("equipe2/{id}/match") 92 | public List getMatchByEquipe2Id(@PathVariable Long id) { 93 | return es.getMatchByEquipe2Id(id); 94 | } 95 | 96 | @PutMapping("equipe") 97 | public Equipe updateEquipe(@RequestBody Equipe e) { 98 | 99 | return es.addEquipe(e); 100 | } 101 | 102 | 103 | @DeleteMapping("equipe/{id}") 104 | public void deleteEquipe(@PathVariable Long id) { 105 | 106 | es.deleteEquipe(id); 107 | } 108 | 109 | 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/controllers/JoueurController.java: -------------------------------------------------------------------------------- 1 | package spring.tp.controllers; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | 7 | import org.springframework.web.bind.annotation.DeleteMapping; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.PutMapping; 12 | import org.springframework.web.bind.annotation.RequestBody; 13 | import org.springframework.web.bind.annotation.RestController; 14 | import spring.tp.services.JoueurService; 15 | import spring.tp.entities.Joueur; 16 | 17 | @RestController 18 | public class JoueurController { 19 | 20 | @Autowired 21 | JoueurService ss; 22 | 23 | @GetMapping("joueur") 24 | public List getAllJoueurs(){ 25 | return ss.getAllJoueurs(); 26 | } 27 | @PostMapping("joueur") 28 | public Joueur addJoueur(@RequestBody Joueur s) { 29 | return ss.addJoueur(s); 30 | } 31 | @DeleteMapping("joueur/{id}") 32 | public void deleteJoueur(@PathVariable Long id) { 33 | ss.deleteJoueur(id); 34 | } 35 | @PutMapping("joueur") 36 | public Joueur updateJoueur(@RequestBody Joueur s) { 37 | return ss.updateJoueur(s); 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/controllers/MatcheController.java: -------------------------------------------------------------------------------- 1 | package spring.tp.controllers; 2 | 3 | import java.time.LocalDate; 4 | 5 | import java.util.List; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | import org.springframework.format.annotation.DateTimeFormat; 10 | import org.springframework.web.bind.annotation.DeleteMapping; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PathVariable; 13 | import org.springframework.web.bind.annotation.PostMapping; 14 | import org.springframework.web.bind.annotation.PutMapping; 15 | import org.springframework.web.bind.annotation.RequestBody; 16 | import org.springframework.web.bind.annotation.RestController; 17 | 18 | import spring.tp.entities.Equipe; 19 | import spring.tp.entities.Matche; 20 | import spring.tp.entities.Stade; 21 | import spring.tp.services.MatcheService; 22 | 23 | 24 | 25 | 26 | @RestController 27 | public class MatcheController { 28 | 29 | @Autowired 30 | MatcheService ms; 31 | 32 | @GetMapping("matche") 33 | public List getAllMatches(){ 34 | return ms.getAllMatches(); 35 | } 36 | 37 | @GetMapping("matche/{id}") 38 | public Matche getMatcheById(@PathVariable Long id) { 39 | return ms.getMatcheById(id); 40 | } 41 | 42 | @GetMapping("matche/{id}/stade") 43 | public Stade getStadeByMatcheId(@PathVariable Long id) { 44 | return ms.getStadeByMatcheId(id); 45 | } 46 | @GetMapping("matche/{id}/equipes") 47 | public List getEquipesByMatcheId(@PathVariable Long id) { 48 | return ms.getEquipesByMatcheId(id); 49 | 50 | } 51 | 52 | @GetMapping("matche/date/{date}") 53 | public List findByDateMatchEquals(@PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) { 54 | 55 | return ms.findByDateMatchEquals(date); 56 | 57 | } 58 | @PostMapping("matche") 59 | public Matche addMatche(@RequestBody Matche s) { 60 | return ms.addMatche(s); 61 | } 62 | 63 | @PutMapping("matche") 64 | public Matche updateMatche(@RequestBody Matche s) { 65 | return ms.updateMatche(s); 66 | } 67 | 68 | @DeleteMapping("matche/{id}") 69 | public void deleteMatche(@PathVariable Long id) { 70 | ms.deleteMatche(id); 71 | } 72 | 73 | @DeleteMapping("matche") 74 | public List deleteMatchesLessThanNow() { 75 | return ms.deleteMatchesLessThanNow(); 76 | } 77 | 78 | public List getAllMatches(int page, int size, String feild){ 79 | return ms.getAllMatches(page, size, feild); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/controllers/StadeController.java: -------------------------------------------------------------------------------- 1 | package spring.tp.controllers; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.DeleteMapping; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.PutMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import spring.tp.entities.Stade; 15 | import spring.tp.entities.Matche; 16 | import spring.tp.services.StadeService; 17 | 18 | @RestController 19 | public class StadeController { 20 | 21 | @Autowired 22 | StadeService ss; 23 | 24 | @PostMapping("stade") 25 | public Stade addStade(@RequestBody Stade g) { 26 | return ss.addStade(g); 27 | } 28 | 29 | @GetMapping("stade") 30 | List getAllStades(){ 31 | return ss.getAllStades(); 32 | } 33 | 34 | 35 | @GetMapping("stade/{id}") 36 | public Stade getStadeById(@PathVariable Long id) { 37 | return ss.getStadeById(id); 38 | 39 | } 40 | 41 | @GetMapping("stade/{id}/matche") 42 | public List getMatcheByStadeId(@PathVariable Long id) { 43 | 44 | return ss.getMatcheByStadeId(id); 45 | } 46 | 47 | @PostMapping("stade/{id}/matche/{id2}") 48 | public Matche addMatcheTostade(@PathVariable Long id, @RequestBody Matche m, @PathVariable Long id2) { 49 | return ss.addMatcheTostade(id, m, id2); 50 | } 51 | 52 | @DeleteMapping("stade/{id}") 53 | public void deleteStade(@PathVariable Long id) { 54 | ss.deleteStade(id); 55 | } 56 | 57 | @PutMapping("stade") 58 | public Stade updateStade(@RequestBody Stade s) { 59 | return ss.updateStade(s); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/entities/Arbitre.java: -------------------------------------------------------------------------------- 1 | package spring.tp.entities; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnore; 6 | 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.OneToMany; 12 | import lombok.AllArgsConstructor; 13 | import lombok.Data; 14 | import lombok.NoArgsConstructor; 15 | 16 | 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Entity 21 | public class Arbitre { 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.IDENTITY) 24 | Long id; 25 | String nom; 26 | String nationality; 27 | 28 | @OneToMany(mappedBy = "arbitre") 29 | @JsonIgnore //on recupere list de groups we ignore the students, because if we want to recupere a student it will recupere id nom et note et son groupe ( et groupe contient id nom and students, we ignore students) 30 | List matches; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/entities/Equipe.java: -------------------------------------------------------------------------------- 1 | package spring.tp.entities; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnore; 6 | 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.OneToMany; 12 | import lombok.AllArgsConstructor; 13 | import lombok.Data; 14 | import lombok.NoArgsConstructor; 15 | 16 | 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Entity 21 | public class Equipe { 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.IDENTITY) 24 | Long id; 25 | String nom; 26 | String pays; 27 | 28 | @OneToMany(mappedBy = "equipe1") 29 | @JsonIgnore 30 | List matchesAsEquipe1; 31 | 32 | @OneToMany(mappedBy = "equipe2") 33 | @JsonIgnore 34 | List matchesAsEquipe2; 35 | 36 | @OneToMany(mappedBy = "equipe") 37 | @JsonIgnore //on recupere list de groups we ignore the students, because if we want to recupere a student it will recupere id nom et note et son groupe ( et groupe contient id nom and students, we ignore students) 38 | List joueurs; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/entities/Joueur.java: -------------------------------------------------------------------------------- 1 | package spring.tp.entities; 2 | 3 | import jakarta.persistence.Entity; 4 | import jakarta.persistence.GeneratedValue; 5 | import jakarta.persistence.GenerationType; 6 | import jakarta.persistence.Id; 7 | import jakarta.persistence.ManyToOne; 8 | import lombok.AllArgsConstructor; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Entity 17 | public class Joueur { 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | Long id; 21 | String nom; 22 | String poste; 23 | 24 | @ManyToOne 25 | Equipe equipe; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/entities/Matche.java: -------------------------------------------------------------------------------- 1 | package spring.tp.entities; 2 | 3 | import java.util.Date; 4 | 5 | import jakarta.persistence.Entity; 6 | import jakarta.persistence.GeneratedValue; 7 | import jakarta.persistence.GenerationType; 8 | import jakarta.persistence.Id; 9 | import jakarta.persistence.JoinColumn; 10 | import jakarta.persistence.ManyToOne; 11 | import jakarta.persistence.Temporal; 12 | import jakarta.persistence.TemporalType; 13 | import lombok.AllArgsConstructor; 14 | import lombok.Data; 15 | import lombok.NoArgsConstructor; 16 | 17 | 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Entity 22 | public class Matche { 23 | @Id 24 | @GeneratedValue(strategy = GenerationType.IDENTITY) 25 | Long id; 26 | @Temporal(TemporalType.DATE) 27 | private Date dateMatch; 28 | 29 | private String hourMatch; 30 | 31 | @ManyToOne 32 | private Stade stade; 33 | 34 | @ManyToOne 35 | @JoinColumn(name = "equipe1_id") 36 | private Equipe equipe1; 37 | 38 | @ManyToOne 39 | @JoinColumn(name = "equipe2_id") 40 | private Equipe equipe2; 41 | 42 | @ManyToOne 43 | private Arbitre arbitre; 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/entities/Stade.java: -------------------------------------------------------------------------------- 1 | package spring.tp.entities; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnore; 6 | 7 | import jakarta.persistence.Entity; 8 | import jakarta.persistence.GeneratedValue; 9 | import jakarta.persistence.GenerationType; 10 | import jakarta.persistence.Id; 11 | import jakarta.persistence.OneToMany; 12 | import lombok.AllArgsConstructor; 13 | import lombok.Data; 14 | import lombok.NoArgsConstructor; 15 | 16 | 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | @Entity 21 | public class Stade { 22 | @Id 23 | @GeneratedValue(strategy = GenerationType.IDENTITY) 24 | Long id; 25 | String nom; 26 | String ville; 27 | 28 | @OneToMany(mappedBy = "stade") 29 | @JsonIgnore //on recupere list de groups we ignore the students, because if we want to recupere a student it will recupere id nom et note et son groupe ( et groupe contient id nom and students, we ignore students) 30 | List matches; 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/repositories/ArbitreRepository.java: -------------------------------------------------------------------------------- 1 | package spring.tp.repositories; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import spring.tp.entities.Arbitre; 7 | 8 | @Repository 9 | public interface ArbitreRepository extends JpaRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/repositories/EquipeRepository.java: -------------------------------------------------------------------------------- 1 | package spring.tp.repositories; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import spring.tp.entities.Equipe; 9 | 10 | @Repository 11 | public interface EquipeRepository extends JpaRepository { 12 | 13 | List findByPaysIgnoreCase(String nom); 14 | Equipe findByNom(String nom); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/repositories/JoueurRepository.java: -------------------------------------------------------------------------------- 1 | package spring.tp.repositories; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import spring.tp.entities.Equipe; 9 | import spring.tp.entities.Joueur; 10 | 11 | 12 | @Repository 13 | public interface JoueurRepository extends JpaRepository { 14 | 15 | List findByEquipe(Equipe a); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/repositories/MatcheRepository.java: -------------------------------------------------------------------------------- 1 | package spring.tp.repositories; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import spring.tp.entities.Arbitre; 10 | import spring.tp.entities.Equipe; 11 | import spring.tp.entities.Matche; 12 | import spring.tp.entities.Stade; 13 | 14 | 15 | @Repository 16 | public interface MatcheRepository extends JpaRepository { 17 | List findByArbitre(Arbitre a); 18 | List findByStade(Stade a); 19 | List findByEquipe1(Equipe a); 20 | List findByEquipe2(Equipe a); 21 | List findByDateMatchEquals(Date a); 22 | List findByDateMatchLessThan(Date a); 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/repositories/StadeRepository.java: -------------------------------------------------------------------------------- 1 | package spring.tp.repositories; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import spring.tp.entities.Stade; 7 | 8 | @Repository 9 | public interface StadeRepository extends JpaRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/services/ArbitreService.java: -------------------------------------------------------------------------------- 1 | package spring.tp.services; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | 9 | import jakarta.persistence.EntityNotFoundException; 10 | import spring.tp.entities.Arbitre; 11 | import spring.tp.entities.Matche; 12 | import spring.tp.repositories.ArbitreRepository; 13 | import spring.tp.repositories.MatcheRepository; 14 | 15 | @Service 16 | public class ArbitreService { 17 | 18 | @Autowired 19 | ArbitreRepository ar; 20 | @Autowired 21 | MatcheRepository mr; 22 | 23 | public Arbitre addArbitre( Arbitre g) { 24 | return ar.save(g); 25 | } 26 | 27 | public Matche addMatcheToArbitre( Long id, Matche m, Long id2) { 28 | Arbitre e= ar.findById(id).orElseThrow(() -> new EntityNotFoundException("Arbitre not found")); 29 | Matche m2= mr.findById(id2).orElse(null); 30 | //System.out.println(m2); 31 | if(m2==null) {m.setArbitre(e); return mr.save(m);} 32 | else {m2.setArbitre(e); 33 | return mr.save(m2);} 34 | } 35 | 36 | public List getAllArbitres(){ 37 | return ar.findAll(); 38 | } 39 | 40 | 41 | public Arbitre getArbitreById( Long id) { 42 | return ar.findById(id).get(); 43 | 44 | } 45 | 46 | public List getMatcheByarbitreId( Long id) { 47 | Arbitre g = ar.findById(id).get(); 48 | //we pass that group 49 | return mr.findByArbitre(g); 50 | } 51 | 52 | public void deleteArbitre( Long id) { 53 | List matches=getMatcheByarbitreId(id); 54 | matches.forEach(m->{//expression lambda 55 | m.setArbitre(null); 56 | }); 57 | ar.deleteById(id); 58 | } 59 | 60 | public Arbitre updateArbitre( Arbitre s) { 61 | return ar.save(s); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/services/EquipeService.java: -------------------------------------------------------------------------------- 1 | package spring.tp.services; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import jakarta.persistence.EntityNotFoundException; 10 | import spring.tp.entities.Equipe; 11 | import spring.tp.entities.Joueur; 12 | import spring.tp.entities.Matche; 13 | import spring.tp.repositories.EquipeRepository; 14 | import spring.tp.repositories.JoueurRepository; 15 | import spring.tp.repositories.MatcheRepository; 16 | 17 | @Service 18 | public class EquipeService { 19 | 20 | @Autowired 21 | EquipeRepository er; 22 | @Autowired 23 | JoueurRepository jr; 24 | @Autowired 25 | MatcheRepository mr; 26 | 27 | public Equipe addEquipe( Equipe e) { 28 | return er.save(e); 29 | } 30 | 31 | public List getAllEquipes(){ 32 | return er.findAll(); 33 | } 34 | 35 | public Equipe getEquipeById( Long id) { 36 | return er.findById(id).get(); 37 | } 38 | 39 | //we'll add player to equipe with id in url 40 | public Joueur addJoueurToEquipe( Long id, Joueur m) { 41 | Equipe e= er.findById(id).get(); 42 | m.setEquipe(e); 43 | return jr.save(m); 44 | } 45 | 46 | public List findByPays() { 47 | 48 | return er.findByPaysIgnoreCase("Maroc"); 49 | } 50 | 51 | //show list of players that belongs to an equipe with id url 52 | public List getJoueurByEquipeId( Long id) { 53 | Equipe e = er.findById(id).get(); 54 | return jr.findByEquipe(e); 55 | } 56 | 57 | //show list of players that belongs to an equipe with nom in url 58 | public List getJoueurByEquipeNom( String nom) { 59 | Equipe e = er.findByNom(nom); 60 | return jr.findByEquipe(e); 61 | } 62 | 63 | public List getJoueurByEquipeNomAndPost( String nom, String post) { 64 | Equipe e = er.findByNom(nom); 65 | //System.out.println(e.getNom()); 66 | 67 | List joueurs= jr.findByEquipe(e); 68 | System.out.println(joueurs.isEmpty()); 69 | List attaquants = new ArrayList<>(); 70 | joueurs.forEach(m->{//expression lambda 71 | if(m.getPoste().equals(post)) attaquants.add(m); 72 | }); 73 | 74 | return attaquants; 75 | 76 | } 77 | 78 | //we'll add a match to an equipe, as an equipe1, match will save all infos of that equipe as an equipe1 79 | public Matche addMatcheToEquipe1( Long id, Matche m, Long id2) { 80 | //we see if that equipe with first id in url exists we fetch the whole equipe 81 | Equipe e= er.findById(id).orElseThrow(() -> new EntityNotFoundException("Equipe not found")); 82 | //we check if that match already exists, we extract the whole match 83 | Matche m2= mr.findById(id2).orElse(null); 84 | //System.out.println(m2); 85 | //if the match doesn't exist, we take the Matche from body, add equipe 1 and save to bd 86 | if(m2==null) {m.setEquipe1(e); return mr.save(m);} 87 | //or else we take the already ex match, add equipe1 to it and update it 88 | else {m2.setEquipe1(e); 89 | return mr.save(m2);} 90 | } 91 | 92 | public Matche addMatcheToEquipe2( Long id, Matche m, Long id2) { 93 | Equipe e= er.findById(id).orElseThrow(() -> new EntityNotFoundException("Equipe not found")); 94 | Matche m2= mr.findById(id2).orElse(null); 95 | //System.out.println(m2); 96 | if(m2==null) {m.setEquipe2(e); return mr.save(m);} 97 | else m2.setEquipe2(e); 98 | return mr.save(m2); 99 | } 100 | 101 | public List getMatchByEquipe1Id( Long id) { 102 | Equipe e = er.findById(id).get(); 103 | return mr.findByEquipe1(e); 104 | } 105 | 106 | 107 | public List getMatchByEquipe2Id( Long id) { 108 | Equipe e = er.findById(id).get(); 109 | return mr.findByEquipe2(e); 110 | } 111 | 112 | public Equipe updateEquipe( Equipe e) { 113 | return er.save(e); 114 | } 115 | 116 | 117 | public void deleteEquipe( Long id) { 118 | 119 | List joueurs=getJoueurByEquipeId(id); 120 | List matches1=getMatchByEquipe1Id(id); 121 | List matches2=getMatchByEquipe2Id(id); 122 | 123 | joueurs.forEach(m->{//expression lambda 124 | m.setEquipe(null); 125 | }); 126 | matches1.forEach(m->{ 127 | m.setEquipe1(null); 128 | }); 129 | matches2.forEach(m->{ 130 | m.setEquipe2(null); 131 | }); 132 | 133 | er.deleteById(id); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/services/JoueurService.java: -------------------------------------------------------------------------------- 1 | package spring.tp.services; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | 9 | import spring.tp.entities.Joueur; 10 | import spring.tp.repositories.JoueurRepository; 11 | 12 | @Service 13 | public class JoueurService { 14 | 15 | @Autowired 16 | JoueurRepository jr; 17 | 18 | public List getAllJoueurs(){ 19 | return jr.findAll(); 20 | } 21 | public Joueur addJoueur( Joueur s) { 22 | return jr.save(s); 23 | } 24 | public void deleteJoueur( Long id) { 25 | jr.deleteById(id); 26 | } 27 | public Joueur updateJoueur( Joueur s) { 28 | return jr.save(s); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/services/MatcheService.java: -------------------------------------------------------------------------------- 1 | package spring.tp.services; 2 | 3 | import java.time.LocalDate; 4 | import java.util.ArrayList; 5 | import java.util.Date; 6 | import java.util.List; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.domain.Page; 10 | import org.springframework.data.domain.PageRequest; 11 | import org.springframework.data.domain.Pageable; 12 | import org.springframework.data.domain.Sort; 13 | import org.springframework.stereotype.Service; 14 | 15 | 16 | import spring.tp.entities.Equipe; 17 | import spring.tp.entities.Matche; 18 | import spring.tp.entities.Stade; 19 | import spring.tp.repositories.MatcheRepository; 20 | 21 | @Service 22 | public class MatcheService { 23 | 24 | @Autowired 25 | MatcheRepository mr; 26 | 27 | public List getAllMatches(){ 28 | return mr.findAll(); 29 | } 30 | 31 | public Matche getMatcheById( Long id) { 32 | return mr.findById(id).get(); 33 | } 34 | 35 | public Stade getStadeByMatcheId( Long id) { 36 | return mr.findById(id).get().getStade(); 37 | } 38 | public List getEquipesByMatcheId( Long id) { 39 | List equipes=new ArrayList<>() ; 40 | 41 | Equipe equipe1 = mr.findById(id).get().getEquipe1(); 42 | equipes.add(equipe1); 43 | Equipe equipe2 = mr.findById(id).get().getEquipe2(); 44 | equipes.add(equipe2); 45 | return equipes; 46 | 47 | } 48 | 49 | public List findByDateMatchEquals( LocalDate date) { 50 | 51 | Date convertedDate = java.sql.Date.valueOf(date); 52 | return mr.findByDateMatchEquals(convertedDate); 53 | 54 | } 55 | public Matche addMatche( Matche s) { 56 | return mr.save(s); 57 | } 58 | 59 | public Matche updateMatche( Matche s) { 60 | return mr.save(s); 61 | } 62 | 63 | public void deleteMatche( Long id) { 64 | mr.deleteById(id); 65 | } 66 | 67 | public List deleteMatchesLessThanNow() { 68 | List matches= mr.findByDateMatchLessThan(new Date()); 69 | mr.deleteAll(matches); 70 | return matches; 71 | } 72 | 73 | public List getAllMatches(int page, int size, String feild){ 74 | Pageable pg= PageRequest.of(page, size, Sort.by(feild)); 75 | Page MatchesPage = mr.findAll(pg); 76 | return MatchesPage.getContent(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/spring/tp/services/StadeService.java: -------------------------------------------------------------------------------- 1 | package spring.tp.services; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | 9 | import jakarta.persistence.EntityNotFoundException; 10 | import spring.tp.entities.Matche; 11 | import spring.tp.entities.Stade; 12 | import spring.tp.repositories.MatcheRepository; 13 | import spring.tp.repositories.StadeRepository; 14 | 15 | @Service 16 | public class StadeService { 17 | 18 | @Autowired 19 | StadeRepository sr; 20 | @Autowired 21 | MatcheRepository mr; 22 | 23 | public Stade addStade( Stade g) { 24 | return sr.save(g); 25 | } 26 | 27 | public List getAllStades(){ 28 | return sr.findAll(); 29 | } 30 | 31 | 32 | public Stade getStadeById( Long id) { 33 | return sr.findById(id).get(); 34 | 35 | } 36 | 37 | public List getMatcheByStadeId( Long id) { 38 | Stade g = sr.findById(id).get(); 39 | //we pass that group 40 | return mr.findByStade(g); 41 | } 42 | 43 | public Matche addMatcheTostade( Long id, Matche m, Long id2) { 44 | Stade e= sr.findById(id).orElseThrow(() -> new EntityNotFoundException("stade not found")); 45 | Matche m2= mr.findById(id2).orElse(null); 46 | //System.out.println(m2); 47 | if(m2==null) {m.setStade(e); return mr.save(m);} 48 | else {m2.setStade(e); 49 | return mr.save(m2);} 50 | } 51 | 52 | public void deleteStade( Long id) { 53 | List matches=getMatcheByStadeId(id); 54 | matches.forEach(m->{//expression lambda 55 | m.setStade(null); 56 | }); 57 | sr.deleteById(id); 58 | } 59 | 60 | public Stade updateStade( Stade s) { 61 | return sr.save(s); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #spring data use deja hibernate 2 | spring.jpa.hibernate.ddl-auto=update 3 | spring.datasource.url=jdbc:mysql://localhost:3306/springdata 4 | spring.datasource.username=root 5 | spring.datasource.password= 6 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 7 | #pour voir les codes sql generer par spring data lorsque findAll par exemple 8 | spring.jpa.show-sql: true -------------------------------------------------------------------------------- /src/test/java/spring/tp/SpringDataProjectApplicationTests.java: -------------------------------------------------------------------------------- 1 | package spring.tp; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringDataProjectApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------