From 5a9afb74371202b1daba78bed7bbdea752f681cd Mon Sep 17 00:00:00 2001 From: Alexis Drai Date: Sun, 28 May 2023 03:17:45 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=83=EF=B8=8F=20=F0=9F=91=94=20Establis?= =?UTF-8?q?h=20a=20basic=20backend=20(#4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit including: persistence, business logic, OpenAPI specs Co-authored-by: alexis.drai@etu.uca.fr Reviewed-on: https://codefirst.iut.uca.fr/git/alexis.drai/AD_MongoDB/pulls/4 --- .gitignore | 4 + README.md | 20 +- build.gradle | 86 +- docs/DB.md | 82 +- docs/mcd.png | Bin 47961 -> 34422 bytes docs/nosql_uml.png | Bin 52543 -> 51864 bytes .../java/fr/uca/iut/codecs/GenericCodec.java | 89 +- .../fr/uca/iut/codecs/move/MoveCodec.java | 78 + .../iut/codecs/move/MoveCodecProvider.java | 18 + .../iut/codecs/pokemong/PokemongCodec.java | 280 +-- .../pokemong/PokemongCodecProvider.java | 32 +- .../uca/iut/codecs/trainer/TrainerCodec.java | 174 +- .../codecs/trainer/TrainerCodecProvider.java | 34 +- .../fr/uca/iut/codecs/type/TypeCodec.java | 67 - .../iut/codecs/type/TypeCodecProvider.java | 16 - .../fr/uca/iut/codecs/type/TypeCodecUtil.java | 27 + .../iut/controllers/GenericController.java | 108 + .../uca/iut/controllers/MoveController.java | 22 + .../iut/controllers/PokemongController.java | 124 +- .../iut/controllers/TrainerController.java | 22 + .../fr/uca/iut/entities/GenericEntity.java | 64 +- src/main/java/fr/uca/iut/entities/Move.java | 118 +- .../java/fr/uca/iut/entities/Pokemong.java | 246 +-- .../fr/uca/iut/entities/PokemongMove.java | 16 + .../java/fr/uca/iut/entities/Trainer.java | 144 +- .../fr/uca/iut/entities/TrainerPokemong.java | 30 + src/main/java/fr/uca/iut/entities/Type.java | 109 +- src/main/java/fr/uca/iut/package-info.java | 4 + .../iut/repositories/GenericRepository.java | 60 + .../uca/iut/repositories/MoveRepository.java | 32 + .../iut/repositories/PokemongRepository.java | 103 +- .../iut/repositories/TrainerRepository.java | 32 + .../fr/uca/iut/services/GenericService.java | 51 + .../java/fr/uca/iut/services/MoveService.java | 100 + .../fr/uca/iut/services/PokemongService.java | 267 ++- .../fr/uca/iut/services/TrainerService.java | 136 ++ .../java/fr/uca/iut/utils/StringUtils.java | 7 + .../uca/iut/utils/enums/MoveCategoryName.java | 7 + .../iut/utils/{ => enums}/PokemongName.java | 2 +- .../uca/iut/utils/{ => enums}/TypeName.java | 2 +- .../exceptions/NonValidEntityException.java | 7 + src/main/resources/META-INF/openapi.yaml | 1748 +++++++++++++++++ src/main/resources/application.properties | 5 +- 43 files changed, 3565 insertions(+), 1008 deletions(-) create mode 100644 src/main/java/fr/uca/iut/codecs/move/MoveCodec.java create mode 100644 src/main/java/fr/uca/iut/codecs/move/MoveCodecProvider.java delete mode 100644 src/main/java/fr/uca/iut/codecs/type/TypeCodec.java delete mode 100644 src/main/java/fr/uca/iut/codecs/type/TypeCodecProvider.java create mode 100644 src/main/java/fr/uca/iut/codecs/type/TypeCodecUtil.java create mode 100644 src/main/java/fr/uca/iut/controllers/GenericController.java create mode 100644 src/main/java/fr/uca/iut/controllers/MoveController.java create mode 100644 src/main/java/fr/uca/iut/controllers/TrainerController.java create mode 100644 src/main/java/fr/uca/iut/entities/PokemongMove.java create mode 100644 src/main/java/fr/uca/iut/entities/TrainerPokemong.java create mode 100644 src/main/java/fr/uca/iut/package-info.java create mode 100644 src/main/java/fr/uca/iut/repositories/GenericRepository.java create mode 100644 src/main/java/fr/uca/iut/repositories/MoveRepository.java create mode 100644 src/main/java/fr/uca/iut/repositories/TrainerRepository.java create mode 100644 src/main/java/fr/uca/iut/services/GenericService.java create mode 100644 src/main/java/fr/uca/iut/services/MoveService.java create mode 100644 src/main/java/fr/uca/iut/services/TrainerService.java create mode 100644 src/main/java/fr/uca/iut/utils/StringUtils.java create mode 100644 src/main/java/fr/uca/iut/utils/enums/MoveCategoryName.java rename src/main/java/fr/uca/iut/utils/{ => enums}/PokemongName.java (99%) rename src/main/java/fr/uca/iut/utils/{ => enums}/TypeName.java (87%) create mode 100644 src/main/java/fr/uca/iut/utils/exceptions/NonValidEntityException.java create mode 100644 src/main/resources/META-INF/openapi.yaml diff --git a/.gitignore b/.gitignore index 8c967c2..0c6da4a 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,7 @@ gradle-app.setting # Cache of project .gradletasknamecache + +# Others +docs/todos.md +/src/test/resources/application.properties diff --git a/README.md b/README.md index 158c85e..e82d5e6 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,12 @@ The application is developed using the Quarkus framework and uses `MongoDB` as i This application is a RESTful service designed to emulate a basic Pokemong management system. It allows users to perform CRUD operations on Pokemongs, trainers, moves, and types. -
🗂️ See the DCM +### 🗂️ DCM Data Concept Model -
- -
🧬 See the UML Class diagram +### 🧬 UML Class diagram UML Class Diagram -
- ## Prep steps ### ♨️ Java version @@ -83,10 +79,18 @@ You can run the application in dev mode using: ## API testing +### 🏴‍☠️ SwaggerUI + +Thanks to this project's OpenAPI specs, you can explore the API in a lot of ways. +A popular choice is SwaggerUI -- after you run the app, just go to http://localhost:8080/q/swagger-ui and have fun. + +⚠️ Unfortunately, Swagger or Quarkus or SmallRye adds the field `id` to all request examples, but in fact ***you should +not include id** when you POST a new document.* + ### 🩺 API testing tools -It is recommended to use an API testing tool such as [Postman](https://www.postman.com/) -or [Insomnia](https://insomnia.rest/), while playing around with this app. +You can use an API testing tool such as [Postman](https://www.postman.com/) +or [Insomnia](https://insomnia.rest/) to test this app. ### 📱 Front end (later) diff --git a/build.gradle b/build.gradle index 5091209..ae4479e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,43 +1,43 @@ -plugins { - id 'java' - id 'io.quarkus' -} - -repositories { - mavenCentral() - mavenLocal() -} - -dependencies { - // FIXME "Provides transitive vulnerable dependency maven:org.jboss.resteasy:resteasy-core:6.2.1.Final - // CVE-2023-0482 7.8 Creation of Temporary File With Insecure Permissions vulnerability with medium severity found - // Results powered by Checkmarx(c)" - implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") - implementation 'io.quarkus:quarkus-resteasy:3.0.0.Alpha6' - implementation 'io.quarkus:quarkus-resteasy-jackson:3.0.0.Alpha6' - implementation 'io.quarkus:quarkus-arc:3.0.0.Alpha6' - implementation 'io.quarkus:quarkus-mongodb-client:3.0.0.Alpha6' - implementation 'org.mongodb:mongodb-driver-sync:4.9.1' - testImplementation 'io.quarkus:quarkus-junit5:3.0.0.Alpha6' - testImplementation 'io.rest-assured:rest-assured:5.3.0' -} - -group 'fr.uca.iut' -version '1.0-SNAPSHOT' - -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} - -test { - systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager" -} -compileJava { - options.encoding = 'UTF-8' - options.compilerArgs << '-parameters' -} - -compileTestJava { - options.encoding = 'UTF-8' -} +plugins { + id 'java' + id 'io.quarkus' +} + +repositories { + mavenCentral() + mavenLocal() +} + +dependencies { + implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}") + implementation 'io.quarkus:quarkus-resteasy:3.0.0.Alpha6' + implementation 'io.quarkus:quarkus-resteasy-jackson:3.0.0.Alpha6' + implementation 'io.quarkus:quarkus-arc:3.0.0.Alpha6' + implementation 'io.quarkus:quarkus-mongodb-client:3.0.0.Alpha6' + implementation 'org.mongodb:mongodb-driver-sync:4.9.1' + implementation 'org.jetbrains:annotations:24.0.1' + implementation 'io.quarkus:quarkus-smallrye-openapi:2.16.4.Final' + implementation 'io.quarkus:quarkus-swagger-ui:2.16.4.Final' + testImplementation 'io.quarkus:quarkus-junit5:3.0.0.Alpha6' + testImplementation 'io.rest-assured:rest-assured:5.3.0' +} + +group 'fr.uca.iut' +version '1.0-SNAPSHOT' + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +test { + systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager" +} +compileJava { + options.encoding = 'UTF-8' + options.compilerArgs << '-parameters' +} + +compileTestJava { + options.encoding = 'UTF-8' +} diff --git a/docs/DB.md b/docs/DB.md index ce5bce5..f7dfcb2 100644 --- a/docs/DB.md +++ b/docs/DB.md @@ -6,11 +6,11 @@ * _id: ObjectId * name: string - * (_indexed_: would be queried often in a dashboard situation) + * (_indexed_: would often be queried in a dashboard situation) * dob: date * wins: int * losses: int -* past_opponents: array of ObjectId (references to other trainers) +* pastOpponents: array of ObjectId (references to other trainers) * (_indexed_: reflexivity would make deep queries quite slow, so it seems worthwhile) * pokemongs: array of ObjectId (references to owned pokemongs) + denormalizing on "nickname" and "species" * (_indexed_: to improve speed when querying non-denormalized fields) @@ -18,58 +18,70 @@ ### pokemongs collection * _id: ObjectId -* nickname: string +* nickname: string? * dob: date * level: int -* pokedex_id: int -* evo_stage: int - * (_indexed_: "species" is calculated as evo_track[evo_stage], and would be queried often) -* evo_track: array of strings (therefore "species" is evo_track[evo_stage], and "evo_base" is evo_track[0]) - * (_indexed_: "species" is calculated as evo_track[evo_stage], and xould be queried often) -* is_mega_evolved: boolean - * **polymorphic**: this field is only here for mature_pokemongs, i.e. pokemongs who have reached their last evo_stage +* pokedexId: int +* evoStage: int + * (_indexed_: "species" is calculated as evoTrack[evoStage], and would often be queried) +* evoTrack: array of strings (therefore "species" is evoTrack[evoStage], and "evoBase" is evoTrack[0]) + * (_indexed_: "species" is calculated as evoTrack[evoStage], and would be queried often) * trainer: ObjectId? (reference to a trainer) (but can be "wild" instead, if ref is null) * (_indexed_: could be queried often in a dashboard situation) * types: embedded type, or array of embedded types - * (_indexed_: would be queried often in a dashboard situation) -* move_set: array of ObjectId (references to known moves) + denormalizing on "name" + * (_indexed_: would often be queried in a dashboard situation) +* moveSet: array of ObjectId (references to known moves) + denormalizing on "name" ### moves collection * _id: ObjectId * name: string - * (_indexed_: would be queried often in a dashboard situation) + * (_indexed_: would often be queried in a dashboard situation) * category: string (can be "physical", "special", or "status") -* pp: int * power: int - * (_indexed_: would be used often in sorts, in a dashboard situation) + * (_indexed_: would often be used in sorts, in a dashboard situation) * accuracy: int * type: embedded type - * (_indexed_: would be queried often in a dashboard situation) - + * (_indexed_: would often be queried in a dashboard situation) ### types collection * _id: ObjectId * name: string - * (_indexed_: would be queried often in a dashboard situation) -* weak_against: array of strings (denormalized type names) -* effective_against: array of strings (denormalized type names) + * (_indexed_: would often be queried in a dashboard situation) +* weakAgainst: array of strings (denormalized type names) +* effectiveAgainst: array of strings (denormalized type names) ## Relationships -* trainers.past_opponents: one-to-many and reflexive - * => referencing -* trainers.pokemongs: one-to-many - * => referencing + denormalizing on "nickname" and "species" -* pokemongs.trainer: many-to-one - * => referencing -* pokemongs.types: one-to-few [1;2] but will also need to be queried independently - * => denormalizing on all fields -* pokemongs.move_set: one-to-few [1;4] but will also need to be queried independently - * => referencing + denormalizing on "name" -* moves.type: one-to-one [1;1] but will also need to be queried independently - * => denormalizing on all fields -* types.weak_against & types.effective_against: one-to-few but reflexive - * => denormalizing on "name" - \ No newline at end of file +- Trainer + - [x] trainers.pastOpponents: one-to-many and reflexive + * => referencing + - [x] trainers.pokemongs: one-to-many + * => referencing + denormalizing on "nickname" and "species" +- Pokemong + - [x] pokemongs.trainer: many-to-one + * => referencing + - [x] pokemongs.types: one-to-few [1;2] + * => embedding + - [x] pokemongs.moveSet: one-to-few [1;4] but will also need to be queried independently + * => referencing + denormalizing on "name" +- Move + - [x] moves.type: one-to-one [1;1] + * => embedding +- Type + - [x] types.weakAgainst & types.effectiveAgainst: one-to-few, but reflexive + * => denormalizing on "name" + +## Cascades + +- Pokemong + - [x] delete ~> trainer.pokemongs + - [x] update ~> trainer.pokemongs (denormalizing on "nickname" and "species") + - [x] create ~> trainer.pokemongs +- Trainer + - [x] delete ~> pokemong.trainer + - [x] create ~> pokemong.trainer +- Move + - [x] delete ~> pokemong.moveSet + - [x] update ~> pokemong.moveSet (denormalizing on "name") diff --git a/docs/mcd.png b/docs/mcd.png index a8ef40aa62a4fb14cd18618f315b0292456e8000..20e353232df8ca3fbf271cb166e0cae893932c8b 100644 GIT binary patch literal 34422 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�YhBni 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%0ACJ4Tal#o4-$i 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�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 r1s)-4#;bx6c;;7SgYu` literal 52543 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 G&;J8aT2oN~ diff --git a/src/main/java/fr/uca/iut/codecs/GenericCodec.java b/src/main/java/fr/uca/iut/codecs/GenericCodec.java index c948176..25faad3 100644 --- a/src/main/java/fr/uca/iut/codecs/GenericCodec.java +++ b/src/main/java/fr/uca/iut/codecs/GenericCodec.java @@ -1,48 +1,41 @@ -package fr.uca.iut.codecs; - -import com.mongodb.MongoClientSettings; -import fr.uca.iut.entities.GenericEntity; -import org.bson.*; -import org.bson.codecs.Codec; -import org.bson.codecs.CollectibleCodec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; -import org.bson.types.ObjectId; - -public abstract class GenericCodec implements CollectibleCodec { - private final Codec documentCodec; - protected GenericCodec() { - this.documentCodec = MongoClientSettings.getDefaultCodecRegistry() - .get(Document.class); - } - - public Codec getDocumentCodec() { - return documentCodec; - } - @Override - public abstract void encode(BsonWriter writer, T entity, EncoderContext encoderContext); - - @Override - public abstract Class getEncoderClass(); - - @Override - public T generateIdIfAbsentFromDocument(T document) { - if (!documentHasId(document)) { - document.setId(new ObjectId().toString()); - } - return document; - } - - @Override - public boolean documentHasId(T document) { - return document.getId() != null; - } - - @Override - public BsonValue getDocumentId(T document) { - return new BsonObjectId(new ObjectId(document.getId())); - } - - @Override - public abstract T decode(BsonReader reader, DecoderContext decoderContext); -} +package fr.uca.iut.codecs; + +import fr.uca.iut.entities.GenericEntity; +import org.bson.BsonObjectId; +import org.bson.BsonReader; +import org.bson.BsonValue; +import org.bson.BsonWriter; +import org.bson.codecs.CollectibleCodec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.types.ObjectId; + +public abstract class GenericCodec implements CollectibleCodec { + + @Override + public abstract void encode(BsonWriter writer, T entity, EncoderContext encoderContext); + + @Override + public abstract Class getEncoderClass(); + + @Override + public T generateIdIfAbsentFromDocument(T document) { + if (!documentHasId(document)) { + document.setId(new ObjectId().toString()); + } + return document; + } + + @Override + public boolean documentHasId(T document) { + return document.getId() != null; + } + + @Override + public BsonValue getDocumentId(T document) { + return new BsonObjectId(new ObjectId(document.getId())); + } + + @Override + public abstract T decode(BsonReader reader, DecoderContext decoderContext); +} diff --git a/src/main/java/fr/uca/iut/codecs/move/MoveCodec.java b/src/main/java/fr/uca/iut/codecs/move/MoveCodec.java new file mode 100644 index 0000000..13b7ec8 --- /dev/null +++ b/src/main/java/fr/uca/iut/codecs/move/MoveCodec.java @@ -0,0 +1,78 @@ +package fr.uca.iut.codecs.move; + +import com.mongodb.MongoClientSettings; +import fr.uca.iut.codecs.GenericCodec; +import fr.uca.iut.codecs.type.TypeCodecUtil; +import fr.uca.iut.entities.Move; +import fr.uca.iut.entities.Type; +import fr.uca.iut.utils.enums.MoveCategoryName; +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.Document; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.types.ObjectId; + +public class MoveCodec extends GenericCodec { + private final Codec documentCodec; + + public MoveCodec() { + this.documentCodec = MongoClientSettings.getDefaultCodecRegistry() + .get(Document.class); + } + + @Override + public void encode(BsonWriter writer, Move move, EncoderContext encoderContext) { + Document doc = new Document(); + + doc.put("_id", new ObjectId(move.getId())); + + doc.put("name", move.getName()); + + doc.put("category", move.getCategory()); + + doc.put("power", move.getPower()); + + doc.put("accuracy", move.getAccuracy()); + + Type moveType = move.getType(); + Document typeDoc = new Document(); + typeDoc.put("name", + moveType.getName() + .toString()); + typeDoc.put("weakAgainst", moveType.getWeakAgainst()); + typeDoc.put("effectiveAgainst", moveType.getEffectiveAgainst()); + doc.put("type", typeDoc); + + documentCodec.encode(writer, doc, encoderContext); + } + + @Override + public Class getEncoderClass() { + return Move.class; + } + + @Override + public Move decode(BsonReader reader, DecoderContext decoderContext) { + Document document = documentCodec.decode(reader, decoderContext); + Move move = new Move(); + + move.setId(document.getObjectId("_id") + .toString()); + + move.setName(document.getString("name")); + + move.setCategory(MoveCategoryName.valueOf(document.getString("category"))); + + move.setPower(document.getInteger("power")); + + move.setAccuracy(document.getInteger("accuracy")); + + Document typeDoc = (Document) document.get("type"); + + move.setType(TypeCodecUtil.extractType(typeDoc)); + + return move; + } +} diff --git a/src/main/java/fr/uca/iut/codecs/move/MoveCodecProvider.java b/src/main/java/fr/uca/iut/codecs/move/MoveCodecProvider.java new file mode 100644 index 0000000..312afd9 --- /dev/null +++ b/src/main/java/fr/uca/iut/codecs/move/MoveCodecProvider.java @@ -0,0 +1,18 @@ +package fr.uca.iut.codecs.move; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.Move; +import org.bson.codecs.Codec; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.codecs.configuration.CodecRegistry; + +public class MoveCodecProvider implements CodecProvider { + @Nullable + @Override + public Codec get(Class clazz, CodecRegistry registry) { + if (clazz.equals(Move.class)) { + return (Codec) new MoveCodec(); + } + return null; + } +} diff --git a/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodec.java b/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodec.java index 0610934..de7c7fa 100644 --- a/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodec.java +++ b/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodec.java @@ -1,127 +1,153 @@ -package fr.uca.iut.codecs.pokemong; - -import com.mongodb.MongoClientSettings; -import fr.uca.iut.codecs.GenericCodec; -import fr.uca.iut.entities.Pokemong; -import fr.uca.iut.entities.Type; -import fr.uca.iut.utils.PokemongName; -import fr.uca.iut.utils.TypeName; -import org.bson.*; -import org.bson.codecs.*; -import org.bson.types.ObjectId; - -import java.time.ZoneId; -import java.util.*; -import java.util.stream.Collectors; - -public class PokemongCodec extends GenericCodec { - private final Codec documentCodec; - - public PokemongCodec() { - this.documentCodec = MongoClientSettings.getDefaultCodecRegistry() - .get(Document.class); - } - - @Override - public void encode(BsonWriter writer, Pokemong pokemong, EncoderContext encoderContext) { - Document doc = new Document(); - doc.put("_id", new ObjectId(pokemong.getId())); - doc.put("nickname", pokemong.getNickname()); - doc.put("dob", - Date.from(pokemong.getDob() - .atStartOfDay(ZoneId.systemDefault()) - .toInstant())); - doc.put("level", pokemong.getLevel()); - doc.put("pokedexId", pokemong.getPokedexId()); - doc.put("evoStage", pokemong.getEvoStage()); - List evoTrack = Optional.ofNullable(pokemong.getEvoTrack()) - .orElse(Collections.emptyList()) - .stream() - .map(Enum::name) - .collect(Collectors.toList()); - - doc.put("evoTrack", evoTrack); - doc.put("isMegaEvolved", pokemong.getMegaEvolved()); - doc.put("trainer", pokemong.getTrainer()); - List types = Optional.ofNullable(pokemong.getTypes()) - .orElse(Collections.emptyList()) - .stream() - .map(type -> { - Document typeDoc = new Document(); - typeDoc.put("name", - type.getName() - .name()); - List weakAgainst = type.getWeakAgainst() - .stream() - .map(Enum::name) - .collect(Collectors.toList()); - typeDoc.put("weakAgainst", weakAgainst); - List effectiveAgainst = type.getEffectiveAgainst() - .stream() - .map(Enum::name) - .collect(Collectors.toList()); - typeDoc.put("effectiveAgainst", effectiveAgainst); - return typeDoc; - }) - .collect(Collectors.toList()); - doc.put("types", types); - doc.put("moveSet", pokemong.getMoveSet()); - documentCodec.encode(writer, doc, encoderContext); - } - - @Override - public Class getEncoderClass() { - return Pokemong.class; - } - - @Override - public Pokemong decode(BsonReader reader, DecoderContext decoderContext) { - Document document = documentCodec.decode(reader, decoderContext); - Pokemong pokemong = new Pokemong(); - pokemong.setId(document.getObjectId("_id").toString()); - pokemong.setNickname(document.getString("nickname")); - Date dob = document.getDate("dob"); - if (dob != null) { - pokemong.setDob(dob.toInstant() - .atZone(ZoneId.systemDefault()) - .toLocalDate()); - } - pokemong.setPokedexId(document.getInteger("pokedexId")); - pokemong.setEvoStage(document.getInteger("evoStage")); - List evoTrack = Optional.ofNullable((List) document.get("evoTrack")) - .orElse(Collections.emptyList()) - .stream() - .map(PokemongName::valueOf) - .collect(Collectors.toList()); - pokemong.setEvoTrack(evoTrack); - pokemong.setMegaEvolved(document.getBoolean("isMegaEvolved")); - pokemong.setTrainer(document.getObjectId("trainer")); - List types = Optional.ofNullable((List) document.get("types")) - .orElse(Collections.emptyList()) - .stream() - .map(typeDoc -> { - Type type = new Type(); - type.setName(TypeName.valueOf(typeDoc.getString("name"))); - List weakAgainst = Optional - .ofNullable((List) typeDoc.get("weakAgainst")) - .orElse(Collections.emptyList()) - .stream() - .map(TypeName::valueOf) - .collect(Collectors.toList()); - type.setWeakAgainst(weakAgainst); - List effectiveAgainst = Optional - .ofNullable((List) typeDoc.get("effectiveAgainst")) - .orElse(Collections.emptyList()) - .stream() - .map(TypeName::valueOf) - .collect(Collectors.toList()); - type.setEffectiveAgainst(effectiveAgainst); - return type; - }) - .collect(Collectors.toList()); - pokemong.setTypes(types); - pokemong.setMoveSet(Optional.ofNullable(document.getList("moveSet", ObjectId.class)) - .orElse(Collections.emptyList())); - return pokemong; - } -} +package fr.uca.iut.codecs.pokemong; + +import com.mongodb.MongoClientSettings; +import fr.uca.iut.codecs.GenericCodec; +import fr.uca.iut.codecs.type.TypeCodecUtil; +import fr.uca.iut.entities.Pokemong; +import fr.uca.iut.entities.PokemongMove; +import fr.uca.iut.entities.Type; +import fr.uca.iut.utils.enums.PokemongName; +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.Document; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.types.ObjectId; + +import java.time.ZoneId; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class PokemongCodec extends GenericCodec { + private final Codec documentCodec; + + public PokemongCodec() { + this.documentCodec = MongoClientSettings.getDefaultCodecRegistry() + .get(Document.class); + } + + @Override + public void encode(BsonWriter writer, Pokemong pokemong, EncoderContext encoderContext) { + Document doc = new Document(); + + doc.put("_id", new ObjectId(pokemong.getId())); + + doc.put("nickname", pokemong.getNickname()); + + doc.put("dob", + Date.from(pokemong.getDob() + .atStartOfDay(ZoneId.systemDefault()) + .toInstant())); + + doc.put("level", pokemong.getLevel()); + + doc.put("pokedexId", pokemong.getPokedexId()); + + doc.put("evoStage", pokemong.getEvoStage()); + + List evoTrack = pokemong.getEvoTrack() + .stream() + .map(Enum::name) + .collect(Collectors.toList()); + doc.put("evoTrack", evoTrack); + + if (pokemong.getTrainer() != null) { + doc.put("trainer", new ObjectId(pokemong.getTrainer())); + } + + List types = pokemong.getTypes() + .stream() + .map(type -> { + Document typeDoc = new Document(); + typeDoc.put("name", + type.getName() + .name()); + List weakAgainst = type.getWeakAgainst() + .stream() + .map(Enum::name) + .collect(Collectors.toList()); + typeDoc.put("weakAgainst", weakAgainst); + List effectiveAgainst = type.getEffectiveAgainst() + .stream() + .map(Enum::name) + .collect(Collectors.toList()); + typeDoc.put("effectiveAgainst", effectiveAgainst); + return typeDoc; + }) + .collect(Collectors.toList()); + doc.put("types", types); + + List moveSetDocs = pokemong.getMoveSet() + .stream() + .map(move -> { + Document moveDoc = new Document(); + moveDoc.put("_id", new ObjectId(move.getId())); + moveDoc.put("name", move.getName()); + return moveDoc; + }) + .collect(Collectors.toList()); + doc.put("moveSet", moveSetDocs); + + documentCodec.encode(writer, doc, encoderContext); + } + + @Override + public Class getEncoderClass() { + return Pokemong.class; + } + + @Override + public Pokemong decode(BsonReader reader, DecoderContext decoderContext) { + Document document = documentCodec.decode(reader, decoderContext); + Pokemong pokemong = new Pokemong(); + + pokemong.setId(document.getObjectId("_id") + .toString()); + + pokemong.setNickname(document.getString("nickname")); + + Date dob = document.getDate("dob"); + if (dob != null) { + pokemong.setDob(dob.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate()); + } + + pokemong.setLevel(document.getInteger("level")); + + pokemong.setPokedexId(document.getInteger("pokedexId")); + + pokemong.setEvoStage(document.getInteger("evoStage")); + + List evoTrack = document.getList("evoTrack", String.class) + .stream() + .map(PokemongName::valueOf) + .collect(Collectors.toList()); + pokemong.setEvoTrack(evoTrack); + + pokemong.setTrainer(document.getObjectId("trainer") + .toString()); + + List types = document.getList("types", Document.class) + .stream() + .map(TypeCodecUtil::extractType) + .collect(Collectors.toList()); + pokemong.setTypes(types); + + Set moveSet = document.getList("moveSet", Document.class) + .stream() + .map(pokemongMoveDoc -> { + PokemongMove move = new PokemongMove(); + move.setId(((ObjectId) pokemongMoveDoc.get("_id")).toString()); + move.setName(pokemongMoveDoc.getString("name")); + return move; + }) + .collect(Collectors.toSet()); + pokemong.setMoveSet(moveSet); + + return pokemong; + } +} diff --git a/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodecProvider.java b/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodecProvider.java index 376412f..7327c19 100644 --- a/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodecProvider.java +++ b/src/main/java/fr/uca/iut/codecs/pokemong/PokemongCodecProvider.java @@ -1,16 +1,18 @@ -package fr.uca.iut.codecs.pokemong; - -import fr.uca.iut.entities.Pokemong; -import org.bson.codecs.Codec; -import org.bson.codecs.configuration.CodecProvider; -import org.bson.codecs.configuration.CodecRegistry; - -public class PokemongCodecProvider implements CodecProvider { - @Override - public Codec get(Class clazz, CodecRegistry registry) { - if (clazz.equals(Pokemong.class)) { - return (Codec) new PokemongCodec(); - } - return null; - } +package fr.uca.iut.codecs.pokemong; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.Pokemong; +import org.bson.codecs.Codec; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.codecs.configuration.CodecRegistry; + +public class PokemongCodecProvider implements CodecProvider { + @Nullable + @Override + public Codec get(Class clazz, CodecRegistry registry) { + if (clazz.equals(Pokemong.class)) { + return (Codec) new PokemongCodec(); + } + return null; + } } \ No newline at end of file diff --git a/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodec.java b/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodec.java index ea2a396..f9c0041 100644 --- a/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodec.java +++ b/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodec.java @@ -1,57 +1,117 @@ -package fr.uca.iut.codecs.trainer; - -import com.mongodb.MongoClientSettings; -import fr.uca.iut.codecs.GenericCodec; -import fr.uca.iut.entities.Trainer; -import org.bson.*; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; -import org.bson.types.ObjectId; - -import java.time.ZoneId; -import java.util.Date; - -public class TrainerCodec extends GenericCodec { - private final Codec documentCodec; - - public TrainerCodec() { - this.documentCodec = MongoClientSettings.getDefaultCodecRegistry() - .get(Document.class); - } - - @Override - public void encode(BsonWriter writer, Trainer trainer, EncoderContext encoderContext) { - Document doc = new Document(); - doc.put("_id", new ObjectId(trainer.getId())); - doc.put("name", trainer.getName()); - doc.put("dob", Date.from(trainer.getDob().atStartOfDay(ZoneId.systemDefault()).toInstant())); - doc.put("wins", trainer.getWins()); - doc.put("losses", trainer.getLosses()); - doc.put("pastOpponents", trainer.getPastOpponents()); - doc.put("pokemongs", trainer.getPokemongs()); - documentCodec.encode(writer, doc, encoderContext); - } - - @Override - public Class getEncoderClass() { - return Trainer.class; - } - - @Override - public Trainer decode(BsonReader reader, DecoderContext decoderContext) { - Document document = documentCodec.decode(reader, decoderContext); - Trainer trainer = new Trainer(); - trainer.setId(document.getObjectId("_id").toString()); - trainer.setName(document.getString("name")); - Date dob = document.getDate("dob"); - if (dob != null) { - trainer.setDob(dob.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); - } - trainer.setWins(document.getInteger("wins", 0)); - trainer.setLosses(document.getInteger("losses", 0)); - trainer.setPastOpponents(document.getList("pastOpponents", ObjectId.class)); - trainer.setPokemongs(document.getList("pokemongs", ObjectId.class)); - return trainer; - } -} +package fr.uca.iut.codecs.trainer; + +import com.mongodb.MongoClientSettings; +import fr.uca.iut.codecs.GenericCodec; +import fr.uca.iut.entities.Trainer; +import fr.uca.iut.entities.TrainerPokemong; +import fr.uca.iut.utils.enums.PokemongName; +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.Document; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.types.ObjectId; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +public class TrainerCodec extends GenericCodec { + private final Codec documentCodec; + + public TrainerCodec() { + this.documentCodec = MongoClientSettings.getDefaultCodecRegistry() + .get(Document.class); + } + + @Override + public void encode(BsonWriter writer, Trainer trainer, EncoderContext encoderContext) { + Document doc = new Document(); + + doc.put("_id", new ObjectId(trainer.getId())); + + doc.put("name", trainer.getName()); + + LocalDate dob = trainer.getDob(); + if (dob != null) { + doc.put("dob", Date.from(dob.atStartOfDay(ZoneId.systemDefault()) + .toInstant())); + } + + doc.put("wins", trainer.getWins()); + + doc.put("losses", trainer.getLosses()); + + List pastOpponentsIds = trainer.getPastOpponents() + .stream() + .map(ObjectId::new) + .collect(Collectors.toList()); + doc.put("pastOpponents", pastOpponentsIds); + + List pokemongListDoc = trainer.getPokemongs() + .stream() + .map(pokemong -> { + Document moveDoc = new Document(); + moveDoc.put("_id", new ObjectId(pokemong.getId())); + moveDoc.put("nickname", pokemong.getNickname()); + moveDoc.put("species", + pokemong.getSpecies() + .name()); + return moveDoc; + }) + .collect(Collectors.toList()); + doc.put("pokemongs", pokemongListDoc); + + documentCodec.encode(writer, doc, encoderContext); + } + + @Override + public Class getEncoderClass() { + return Trainer.class; + } + + @Override + public Trainer decode(BsonReader reader, DecoderContext decoderContext) { + Document document = documentCodec.decode(reader, decoderContext); + Trainer trainer = new Trainer(); + + trainer.setId(document.getObjectId("_id") + .toString()); + + trainer.setName(document.getString("name")); + + Date dob = document.getDate("dob"); + if (dob != null) { + trainer.setDob(dob.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate()); + } + + trainer.setWins(document.getInteger("wins")); + + trainer.setLosses(document.getInteger("losses")); + + List pastOpponentsIds = document.getList("pastOpponents", ObjectId.class) + .stream() + .map(ObjectId::toString) + .collect(Collectors.toList()); + trainer.setPastOpponents(pastOpponentsIds); + + List pokemongList = document + .getList("pokemongs", Document.class) + .stream() + .map(pokemongDoc -> { + TrainerPokemong pokemong = new TrainerPokemong(); + pokemong.setId(((ObjectId) pokemongDoc.get("_id")).toString()); + pokemong.setNickname(pokemongDoc.getString("nickname")); + pokemong.setSpecies(PokemongName.valueOf(pokemongDoc.getString("species"))); + return pokemong; + }) + .collect(Collectors.toList()); + trainer.setPokemongs(pokemongList); + return trainer; + } +} diff --git a/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodecProvider.java b/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodecProvider.java index 80c178e..0c3e37a 100644 --- a/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodecProvider.java +++ b/src/main/java/fr/uca/iut/codecs/trainer/TrainerCodecProvider.java @@ -1,16 +1,18 @@ -package fr.uca.iut.codecs.trainer; - -import fr.uca.iut.entities.Trainer; -import org.bson.codecs.Codec; -import org.bson.codecs.configuration.CodecProvider; -import org.bson.codecs.configuration.CodecRegistry; - -public class TrainerCodecProvider implements CodecProvider { - @Override - public Codec get(Class clazz, CodecRegistry registry) { - if (clazz.equals(Trainer.class)) { - return (Codec) new TrainerCodec(); - } - return null; - } -} +package fr.uca.iut.codecs.trainer; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.Trainer; +import org.bson.codecs.Codec; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.codecs.configuration.CodecRegistry; + +public class TrainerCodecProvider implements CodecProvider { + @Nullable + @Override + public Codec get(Class clazz, CodecRegistry registry) { + if (clazz.equals(Trainer.class)) { + return (Codec) new TrainerCodec(); + } + return null; + } +} diff --git a/src/main/java/fr/uca/iut/codecs/type/TypeCodec.java b/src/main/java/fr/uca/iut/codecs/type/TypeCodec.java deleted file mode 100644 index 8b01381..0000000 --- a/src/main/java/fr/uca/iut/codecs/type/TypeCodec.java +++ /dev/null @@ -1,67 +0,0 @@ -package fr.uca.iut.codecs.type; - -import com.mongodb.MongoClientSettings; -import fr.uca.iut.entities.Type; -import fr.uca.iut.utils.TypeName; -import org.bson.*; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -public class TypeCodec implements Codec { - private final Codec documentCodec; - - public TypeCodec() { - this.documentCodec = MongoClientSettings.getDefaultCodecRegistry() - .get(Document.class); - } - - @Override - public void encode(BsonWriter writer, Type type, EncoderContext encoderContext) { - Document doc = new Document(); - Optional.ofNullable(type.getName()) - .map(Enum::name) - .ifPresent(name -> doc.put("name", name)); - - Optional.ofNullable(type.getWeakAgainst()) - .map(weakAgainst -> weakAgainst.stream().map(Enum::name).collect(Collectors.toList())) - .ifPresent(weakAgainst -> doc.put("weakAgainst", weakAgainst)); - - Optional.ofNullable(type.getEffectiveAgainst()) - .map(effectiveAgainst -> effectiveAgainst.stream().map(Enum::name).collect(Collectors.toList())) - .ifPresent(effectiveAgainst -> doc.put("effectiveAgainst", effectiveAgainst)); - - documentCodec.encode(writer, doc, encoderContext); - } - - @Override - public Class getEncoderClass() { - return Type.class; - } - - @Override - public Type decode(BsonReader reader, DecoderContext decoderContext) { - Document document = documentCodec.decode(reader, decoderContext); - Type type = new Type(); - - Optional.ofNullable(document.getString("name")) - .map(TypeName::valueOf) - .ifPresent(type::setName); - - Optional.ofNullable(document.get("weakAgainst")) - .filter(obj -> obj instanceof List) - .map(obj -> ((List) obj).stream().map(TypeName::valueOf).collect(Collectors.toList())) - .ifPresent(type::setWeakAgainst); - - Optional.ofNullable(document.get("effectiveAgainst")) - .filter(obj -> obj instanceof List) - .map(obj -> ((List) obj).stream().map(TypeName::valueOf).collect(Collectors.toList())) - .ifPresent(type::setEffectiveAgainst); - - return type; - } -} diff --git a/src/main/java/fr/uca/iut/codecs/type/TypeCodecProvider.java b/src/main/java/fr/uca/iut/codecs/type/TypeCodecProvider.java deleted file mode 100644 index 4a75c95..0000000 --- a/src/main/java/fr/uca/iut/codecs/type/TypeCodecProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -package fr.uca.iut.codecs.type; - -import fr.uca.iut.entities.Type; -import org.bson.codecs.Codec; -import org.bson.codecs.configuration.CodecProvider; -import org.bson.codecs.configuration.CodecRegistry; - -public class TypeCodecProvider implements CodecProvider { - @Override - public Codec get(Class clazz, CodecRegistry registry) { - if (clazz.equals(Type.class)) { - return (Codec) new TypeCodec(); - } - return null; - } -} diff --git a/src/main/java/fr/uca/iut/codecs/type/TypeCodecUtil.java b/src/main/java/fr/uca/iut/codecs/type/TypeCodecUtil.java new file mode 100644 index 0000000..bd45965 --- /dev/null +++ b/src/main/java/fr/uca/iut/codecs/type/TypeCodecUtil.java @@ -0,0 +1,27 @@ +package fr.uca.iut.codecs.type; + +import fr.uca.iut.entities.Type; +import fr.uca.iut.utils.enums.TypeName; +import org.bson.Document; + +import java.util.List; +import java.util.stream.Collectors; + +public class TypeCodecUtil { + public static Type extractType(Document typeDoc) { + Type type = new Type(); + type.setName(TypeName.valueOf(typeDoc.getString("name"))); + List weakAgainst = typeDoc.getList("weakAgainst", String.class) + .stream() + .map(TypeName::valueOf) + .collect(Collectors.toList()); + type.setWeakAgainst(weakAgainst); + List effectiveAgainst = typeDoc.getList("effectiveAgainst", + String.class) + .stream() + .map(TypeName::valueOf) + .collect(Collectors.toList()); + type.setEffectiveAgainst(effectiveAgainst); + return type; + } +} diff --git a/src/main/java/fr/uca/iut/controllers/GenericController.java b/src/main/java/fr/uca/iut/controllers/GenericController.java new file mode 100644 index 0000000..70b30d2 --- /dev/null +++ b/src/main/java/fr/uca/iut/controllers/GenericController.java @@ -0,0 +1,108 @@ +package fr.uca.iut.controllers; + +import fr.uca.iut.entities.GenericEntity; +import fr.uca.iut.services.GenericService; +import fr.uca.iut.utils.exceptions.NonValidEntityException; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +public abstract class GenericController { + + protected GenericService service; + + public void setService(GenericService service) { + this.service = service; + } + + @GET + @Path("/{id}") + public Response getOneById(@PathParam("id") String id) { + try { + T entity = service.getOneById(id); + if (entity != null) { + return Response.ok(entity) + .build(); + } + else { + return Response.status(Response.Status.NOT_FOUND) + .entity("Entity not found for id: " + id) + .build(); + } + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid id format: " + id) + .build(); + } + } + + @GET + public Response getAll() { + return Response.ok(service.getAll()) + .build(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response createOne(T entity) { + + try { + service.validateOne(entity); + T newEntity = service.addOne(entity); + + return Response.status(Response.Status.CREATED) + .entity(newEntity) + .build(); + + } catch (NonValidEntityException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } + } + + @PUT + @Path("/{id}") + @Consumes(MediaType.APPLICATION_JSON) + public Response updateOne(@PathParam("id") String id, T entity) { + try { + service.validateOne(entity); + entity.setId(id); + T updatedEntity = service.updateOne(entity); + + if (updatedEntity != null) { + return Response.status(Response.Status.OK) + .entity(updatedEntity) + .build(); + } + else { + return Response.status(Response.Status.NOT_FOUND) + .entity("Entity not found for id: " + id) + .build(); + } + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid id format: " + id) + .build(); + } catch (NonValidEntityException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(e.getMessage()) + .build(); + } + } + + @DELETE + @Path("/{id}") + public Response deleteOneById(@PathParam("id") String id) { + try { + service.deleteOneById(id); + return Response.ok() + .build(); + + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity("Invalid id format: " + id) + .build(); + } + } +} diff --git a/src/main/java/fr/uca/iut/controllers/MoveController.java b/src/main/java/fr/uca/iut/controllers/MoveController.java new file mode 100644 index 0000000..ff4dbaf --- /dev/null +++ b/src/main/java/fr/uca/iut/controllers/MoveController.java @@ -0,0 +1,22 @@ +package fr.uca.iut.controllers; + +import fr.uca.iut.entities.Move; +import fr.uca.iut.services.MoveService; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/move") +@Produces(MediaType.APPLICATION_JSON) +public class MoveController extends GenericController { + + @Inject + MoveService moveService; + + @PostConstruct + public void init() { + setService(moveService); + } +} diff --git a/src/main/java/fr/uca/iut/controllers/PokemongController.java b/src/main/java/fr/uca/iut/controllers/PokemongController.java index 9032f87..43f4000 100644 --- a/src/main/java/fr/uca/iut/controllers/PokemongController.java +++ b/src/main/java/fr/uca/iut/controllers/PokemongController.java @@ -1,102 +1,22 @@ -package fr.uca.iut.controllers; - -import fr.uca.iut.entities.Pokemong; -import fr.uca.iut.services.PokemongService; -import jakarta.inject.Inject; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; - -@Path("/pokemong") -@Produces(MediaType.APPLICATION_JSON) -public class PokemongController { - - @Inject - PokemongService pokemongService; - - @GET - @Path("/{id}") - public Response getPokemong(@PathParam("id") String id) { - try { - Pokemong pokemong = pokemongService.getPokemong(id); - if (pokemong != null) { - return Response.ok(pokemong) - .build(); - } - else { - return Response.status(Response.Status.NOT_FOUND) - .entity("Pokemong not found for id: " + id) - .build(); - } - } catch (IllegalArgumentException e) { - return Response.status(Response.Status.BAD_REQUEST) - .entity("Invalid id format: " + id) - .build(); - } - } - - @GET - public Response getAllPokemongs() { - return Response.ok(pokemongService.getAllPokemongs()) - .build(); - } - - @POST - @Consumes(MediaType.APPLICATION_JSON) - public Response createPokemong(Pokemong pokemong) { - - if (pokemongService.isNotMature(pokemong)) { - pokemong.setMegaEvolved(null); - } - - Pokemong newPokemong = pokemongService.addPokemong(pokemong); - - return Response.status(Response.Status.CREATED) - .entity(newPokemong) - .build(); - } - - @PUT - @Path("/{id}") - @Consumes(MediaType.APPLICATION_JSON) - public Response updatePokemong(@PathParam("id") String id, Pokemong pokemong) { - try { - if (pokemongService.isNotMature(pokemong)) { - pokemong.setMegaEvolved(null); - } - - pokemong.setId(id); - Pokemong updatedPokemong = pokemongService.updatePokemong(pokemong); - - if (updatedPokemong != null) { - return Response.status(Response.Status.OK) - .entity(updatedPokemong) - .build(); - } - else { - return Response.status(Response.Status.NOT_FOUND) - .entity("Pokemong not found for id: " + id) - .build(); - } - } catch (IllegalArgumentException e) { - return Response.status(Response.Status.BAD_REQUEST) - .entity("Invalid id format: " + id) - .build(); - } - } - - @DELETE - @Path("/{id}") - public Response deletePokemong(@PathParam("id") String id) { - try { - pokemongService.deletePokemong(id); - return Response.ok() - .build(); - - } catch (IllegalArgumentException e) { - return Response.status(Response.Status.BAD_REQUEST) - .entity("Invalid id format: " + id) - .build(); - } - } -} +package fr.uca.iut.controllers; + +import fr.uca.iut.entities.Pokemong; +import fr.uca.iut.services.PokemongService; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/pokemong") +@Produces(MediaType.APPLICATION_JSON) +public class PokemongController extends GenericController { + + @Inject + PokemongService pokemongService; + + @PostConstruct + public void init() { + setService(pokemongService); + } +} diff --git a/src/main/java/fr/uca/iut/controllers/TrainerController.java b/src/main/java/fr/uca/iut/controllers/TrainerController.java new file mode 100644 index 0000000..da58bb3 --- /dev/null +++ b/src/main/java/fr/uca/iut/controllers/TrainerController.java @@ -0,0 +1,22 @@ +package fr.uca.iut.controllers; + +import fr.uca.iut.entities.Trainer; +import fr.uca.iut.services.TrainerService; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/trainer") +@Produces(MediaType.APPLICATION_JSON) +public class TrainerController extends GenericController { + + @Inject + TrainerService trainerService; + + @PostConstruct + public void init() { + setService(trainerService); + } +} diff --git a/src/main/java/fr/uca/iut/entities/GenericEntity.java b/src/main/java/fr/uca/iut/entities/GenericEntity.java index bcfbf04..f98460a 100644 --- a/src/main/java/fr/uca/iut/entities/GenericEntity.java +++ b/src/main/java/fr/uca/iut/entities/GenericEntity.java @@ -1,32 +1,32 @@ -package fr.uca.iut.entities; - -import org.bson.codecs.pojo.annotations.BsonId; - -import java.util.Objects; - -public abstract class GenericEntity { - - @BsonId - private String id; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - @Override - public int hashCode() { - return Objects.hash(id); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GenericEntity entity = (GenericEntity) o; - return Objects.equals(id, entity.id); - } -} +package fr.uca.iut.entities; + +import org.bson.codecs.pojo.annotations.BsonId; + +import java.util.Objects; + +public abstract class GenericEntity { + + @BsonId + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GenericEntity entity = (GenericEntity) o; + return Objects.equals(id, entity.id); + } +} diff --git a/src/main/java/fr/uca/iut/entities/Move.java b/src/main/java/fr/uca/iut/entities/Move.java index d0dacc0..da98c37 100644 --- a/src/main/java/fr/uca/iut/entities/Move.java +++ b/src/main/java/fr/uca/iut/entities/Move.java @@ -1,65 +1,55 @@ -package fr.uca.iut.entities; - -import org.bson.codecs.pojo.annotations.BsonId; - -public class Move extends GenericEntity { - public static final String COLLECTION_NAME = "moves"; - - @BsonId - private String id; - private String name; - private String category; - private Integer power; - private Integer accuracy; - private Type type; - - public Move() {} - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getCategory() { - return category; - } - - public void setCategory(String category) { - this.category = category; - } - - public Integer getPower() { - return power; - } - - public void setPower(Integer power) { - this.power = power; - } - - public Integer getAccuracy() { - return accuracy; - } - - public void setAccuracy(Integer accuracy) { - this.accuracy = accuracy; - } - - public Type getType() { - return type; - } - - public void setType(Type type) { - this.type = type; - } +package fr.uca.iut.entities; + +import fr.uca.iut.utils.enums.MoveCategoryName; + +public class Move extends GenericEntity { + public static final String COLLECTION_NAME = "moves"; + + private String name; + private MoveCategoryName category; + private Integer power; + private Integer accuracy; + private Type type; + + public Move() {} + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public MoveCategoryName getCategory() { + return category; + } + + public void setCategory(MoveCategoryName category) { + this.category = category; + } + + public Integer getPower() { + return power; + } + + public void setPower(Integer power) { + this.power = power; + } + + public Integer getAccuracy() { + return accuracy; + } + + public void setAccuracy(Integer accuracy) { + this.accuracy = accuracy; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } } \ No newline at end of file diff --git a/src/main/java/fr/uca/iut/entities/Pokemong.java b/src/main/java/fr/uca/iut/entities/Pokemong.java index d55deee..1acd9e4 100644 --- a/src/main/java/fr/uca/iut/entities/Pokemong.java +++ b/src/main/java/fr/uca/iut/entities/Pokemong.java @@ -1,119 +1,127 @@ -package fr.uca.iut.entities; - -import fr.uca.iut.utils.PokemongName; -import org.bson.codecs.pojo.annotations.BsonId; -import org.bson.types.ObjectId; - -import java.time.LocalDate; -import java.util.List; - -public class Pokemong extends GenericEntity { - public static final String COLLECTION_NAME = "pokemongs"; - @BsonId - private String id; - private String nickname; - private LocalDate dob; - private Integer level; - private Integer pokedexId; - private Integer evoStage; - private List evoTrack; - private Boolean isMegaEvolved; - private ObjectId trainer; - private List types; // TODO Bound this within [1;2] (in controller) - private List moveSet; // TODO Bound this within [1;4] (in controller) and denormalize move "name" - - public Pokemong() {} - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getNickname() { - return nickname; - } - - public void setNickname(String nickname) { - this.nickname = nickname; - } - - public LocalDate getDob() { - return dob; - } - - public void setDob(LocalDate dob) { - this.dob = dob; - } - - public Integer getLevel() { - return level; - } - - public void setLevel(Integer level) { - this.level = level; - } - - public Integer getPokedexId() { - return pokedexId; - } - - public void setPokedexId(Integer pokedexId) { - this.pokedexId = pokedexId; - } - - public Integer getEvoStage() { - return evoStage; - } - - public void setEvoStage(Integer evoStage) { - this.evoStage = evoStage; - } - - public List getEvoTrack() { - return evoTrack; - } - - public void setEvoTrack(List evoTrack) { - this.evoTrack = evoTrack; - } - - public Boolean getMegaEvolved() { - return isMegaEvolved; - } - - public void setMegaEvolved(Boolean megaEvolved) { - isMegaEvolved = megaEvolved; - } - - public ObjectId getTrainer() { - return trainer; - } - - public void setTrainer(ObjectId trainer) { - this.trainer = trainer; - } - - // TODO take particular care with collections - - // TODO study the question of encapsulation when it comes to using these dependencies... - public List getTypes() { - return types; - } - - public void setTypes(List types) { - this.types = types; - } - - public List getMoveSet() { - return moveSet; - } - - public void setMoveSet(List moveSet) { - this.moveSet = moveSet; - } - -} - +package fr.uca.iut.entities; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.utils.enums.PokemongName; + +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class Pokemong extends GenericEntity { + public static final String COLLECTION_NAME = "pokemongs"; + + @Nullable + private String nickname; + private LocalDate dob; + private Integer level; + private Integer pokedexId; + private Integer evoStage; + private List evoTrack; + @Nullable + private String trainer; + private List types; + + /** + * pokemong.moveSet: [{_id: ObjectId, name: String}] + */ + private Set moveSet; + + public Pokemong() {} + + @Nullable + public String getNickname() { + return nickname; + } + + public void setNickname(@Nullable String nickname) { + this.nickname = nickname; + } + + public LocalDate getDob() { + return dob; + } + + public void setDob(LocalDate dob) { + this.dob = dob; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public Integer getPokedexId() { + return pokedexId; + } + + public void setPokedexId(Integer pokedexId) { + this.pokedexId = pokedexId; + } + + @Nullable + public String getTrainer() { + return trainer; + } + + public void setTrainer(@Nullable String trainer) { + this.trainer = trainer; + } + + public List getTypes() { + return Collections.unmodifiableList(types); + } + + public void setTypes(List types) { + this.types = types; + } + + public Set getMoveSet() { + return Collections.unmodifiableSet(moveSet); + } + + public void setMoveSet(Set moveSet) { + this.moveSet = moveSet; + } + + public void removeMove(String id) { + PokemongMove pokemongMove = new PokemongMove(); + pokemongMove.setId(id); + moveSet.remove(pokemongMove); + } + + public void updateMove(String id, String name) { + for (PokemongMove move : moveSet) { + if (move.getId() + .equals(id)) + { + move.setName(name); + break; + } + } + } + + public PokemongName getSpecies() { + return getEvoTrack().get(getEvoStage()); + } + + public List getEvoTrack() { + return evoTrack; + } + + public Integer getEvoStage() { + return evoStage; + } + + public void setEvoStage(Integer evoStage) { + this.evoStage = evoStage; + } + + public void setEvoTrack(List evoTrack) { + this.evoTrack = evoTrack; + } +} + diff --git a/src/main/java/fr/uca/iut/entities/PokemongMove.java b/src/main/java/fr/uca/iut/entities/PokemongMove.java new file mode 100644 index 0000000..13c4c31 --- /dev/null +++ b/src/main/java/fr/uca/iut/entities/PokemongMove.java @@ -0,0 +1,16 @@ +package fr.uca.iut.entities; + +public class PokemongMove extends GenericEntity { + + private String name; + + public PokemongMove() {} + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/fr/uca/iut/entities/Trainer.java b/src/main/java/fr/uca/iut/entities/Trainer.java index 7b920e3..6586349 100644 --- a/src/main/java/fr/uca/iut/entities/Trainer.java +++ b/src/main/java/fr/uca/iut/entities/Trainer.java @@ -1,78 +1,66 @@ -package fr.uca.iut.entities; - -import org.bson.codecs.pojo.annotations.BsonId; -import org.bson.types.ObjectId; - -import java.time.LocalDate; -import java.util.List; - -public class Trainer extends GenericEntity { - public static final String COLLECTION_NAME = "trainers"; - - @BsonId - private String id; - private String name; - private LocalDate dob; - private Integer wins; - private Integer losses; - private List pastOpponents; - private List pokemongs; - - public Trainer() {} - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public LocalDate getDob() { - return dob; - } - - public void setDob(LocalDate dob) { - this.dob = dob; - } - - public Integer getWins() { - return wins; - } - - public void setWins(Integer wins) { - this.wins = wins; - } - - public Integer getLosses() { - return losses; - } - - public void setLosses(Integer losses) { - this.losses = losses; - } - - public List getPastOpponents() { - return pastOpponents; - } - - public void setPastOpponents(List pastOpponents) { - this.pastOpponents = pastOpponents; - } - - public List getPokemongs() { - return pokemongs; - } - - public void setPokemongs(List pokemongs) { - this.pokemongs = pokemongs; - } -} +package fr.uca.iut.entities; + +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; + +public class Trainer extends GenericEntity { + public static final String COLLECTION_NAME = "trainers"; + + private String name; + private LocalDate dob; + private Integer wins; + private Integer losses; + private List pastOpponents; + private List pokemongs; + + public Trainer() {} + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public LocalDate getDob() { + return dob; + } + + public void setDob(LocalDate dob) { + this.dob = dob; + } + + public Integer getWins() { + return wins; + } + + public void setWins(Integer wins) { + this.wins = wins; + } + + public Integer getLosses() { + return losses; + } + + public void setLosses(Integer losses) { + this.losses = losses; + } + + public List getPastOpponents() { + return Collections.unmodifiableList(pastOpponents); + } + + public void setPastOpponents(List pastOpponents) { + this.pastOpponents = pastOpponents; + } + + public List getPokemongs() { + return Collections.unmodifiableList(pokemongs); + } + + public void setPokemongs(List pokemongs) { + this.pokemongs = pokemongs; + } +} diff --git a/src/main/java/fr/uca/iut/entities/TrainerPokemong.java b/src/main/java/fr/uca/iut/entities/TrainerPokemong.java new file mode 100644 index 0000000..f63fcb5 --- /dev/null +++ b/src/main/java/fr/uca/iut/entities/TrainerPokemong.java @@ -0,0 +1,30 @@ +package fr.uca.iut.entities; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.utils.enums.PokemongName; + +public class TrainerPokemong extends GenericEntity { + @Nullable + private String nickname; + + private PokemongName species; + + public TrainerPokemong() {} + + @Nullable + public String getNickname() { + return nickname; + } + + public void setNickname(@Nullable String nickname) { + this.nickname = nickname; + } + + public PokemongName getSpecies() { + return species; + } + + public void setSpecies(PokemongName species) { + this.species = species; + } +} diff --git a/src/main/java/fr/uca/iut/entities/Type.java b/src/main/java/fr/uca/iut/entities/Type.java index 6eb5756..f9e3022 100644 --- a/src/main/java/fr/uca/iut/entities/Type.java +++ b/src/main/java/fr/uca/iut/entities/Type.java @@ -1,55 +1,56 @@ -package fr.uca.iut.entities; - -import fr.uca.iut.utils.TypeName; - -import java.util.List; -import java.util.Objects; - -public class Type { - - private TypeName name; - private List weakAgainst; - private List effectiveAgainst; - - public Type() {} - - public TypeName getName() { - return name; - } - - public void setName(TypeName name) { - this.name = name; - } - - public List getWeakAgainst() { - return weakAgainst; - } - - public void setWeakAgainst(List weakAgainst) { - this.weakAgainst = weakAgainst; - } - - public List getEffectiveAgainst() { - return effectiveAgainst; - } - - public void setEffectiveAgainst(List effectiveAgainst) { - this.effectiveAgainst = effectiveAgainst; - } - - @Override - public int hashCode() { - return Objects.hash(name, weakAgainst, effectiveAgainst); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Type type = (Type) o; - return Objects.equals(name, type.name) && - Objects.equals(weakAgainst, type.weakAgainst) && - Objects.equals(effectiveAgainst, type.effectiveAgainst); - } - +package fr.uca.iut.entities; + +import fr.uca.iut.utils.enums.TypeName; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class Type { + + private TypeName name; + private List weakAgainst; + private List effectiveAgainst; + + public Type() {} + + public TypeName getName() { + return name; + } + + public void setName(TypeName name) { + this.name = name; + } + + public List getWeakAgainst() { + return Collections.unmodifiableList(weakAgainst); + } + + public void setWeakAgainst(List weakAgainst) { + this.weakAgainst = weakAgainst; + } + + public List getEffectiveAgainst() { + return Collections.unmodifiableList(effectiveAgainst); + } + + public void setEffectiveAgainst(List effectiveAgainst) { + this.effectiveAgainst = effectiveAgainst; + } + + @Override + public int hashCode() { + return Objects.hash(name, weakAgainst, effectiveAgainst); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Type type = (Type) o; + return Objects.equals(name, type.name) && + Objects.equals(weakAgainst, type.weakAgainst) && + Objects.equals(effectiveAgainst, type.effectiveAgainst); + } + } \ No newline at end of file diff --git a/src/main/java/fr/uca/iut/package-info.java b/src/main/java/fr/uca/iut/package-info.java new file mode 100644 index 0000000..3d301f9 --- /dev/null +++ b/src/main/java/fr/uca/iut/package-info.java @@ -0,0 +1,4 @@ +@NonNullApi +package fr.uca.iut; + +import com.mongodb.lang.NonNullApi; diff --git a/src/main/java/fr/uca/iut/repositories/GenericRepository.java b/src/main/java/fr/uca/iut/repositories/GenericRepository.java new file mode 100644 index 0000000..649e2a4 --- /dev/null +++ b/src/main/java/fr/uca/iut/repositories/GenericRepository.java @@ -0,0 +1,60 @@ +package fr.uca.iut.repositories; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.ReplaceOptions; +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.GenericEntity; +import org.bson.Document; +import org.bson.types.ObjectId; +import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import static com.mongodb.client.model.Filters.eq; + +public abstract class GenericRepository { + protected MongoClient mongoClient; + @ConfigProperty(name = "quarkus.mongodb.database") + String DB_NAME; + + public void setMongoClient(MongoClient mongoClient) { + this.mongoClient = mongoClient; + } + + @Nullable + public T findById(String id) { + return getCollection().find(eq("_id", new ObjectId(id))) + .first(); + } + + protected abstract MongoCollection getCollection(); + + public void persist(@NotNull T entity) { + getCollection().insertOne(entity); + } + + public List listAll() { + return getCollection().find() + .into(new ArrayList<>()); + } + + public void persistOrUpdate(@NotNull T entity) { + getCollection().replaceOne( + eq("_id", new ObjectId(entity.getId())), + entity, + new ReplaceOptions().upsert(true) + ); + } + + public void delete(@NotNull T entity) { + getCollection().deleteOne(eq("_id", new ObjectId(entity.getId()))); + } + + public boolean existsById(String id) { + Document query = new Document("_id", new ObjectId(id)); + return getCollection().countDocuments(query) > 0; + } +} diff --git a/src/main/java/fr/uca/iut/repositories/MoveRepository.java b/src/main/java/fr/uca/iut/repositories/MoveRepository.java new file mode 100644 index 0000000..0226f04 --- /dev/null +++ b/src/main/java/fr/uca/iut/repositories/MoveRepository.java @@ -0,0 +1,32 @@ +package fr.uca.iut.repositories; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import fr.uca.iut.entities.Move; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class MoveRepository extends GenericRepository { + + // FIX?ME + /** + * Warns that "Unsatisfied dependency: no bean matches the injection point" + * but the app works + */ + @Inject + MongoClient mongoClient; + + @PostConstruct + public void init() { + setMongoClient(mongoClient); + } + + @Override + protected MongoCollection getCollection() { + MongoDatabase db = mongoClient.getDatabase(DB_NAME); + return db.getCollection(Move.COLLECTION_NAME, Move.class); + } +} diff --git a/src/main/java/fr/uca/iut/repositories/PokemongRepository.java b/src/main/java/fr/uca/iut/repositories/PokemongRepository.java index f60ec5d..3da2595 100644 --- a/src/main/java/fr/uca/iut/repositories/PokemongRepository.java +++ b/src/main/java/fr/uca/iut/repositories/PokemongRepository.java @@ -1,58 +1,45 @@ -package fr.uca.iut.repositories; - -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; -import com.mongodb.client.model.ReplaceOptions; -import fr.uca.iut.entities.Pokemong; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import org.bson.types.ObjectId; -import org.eclipse.microprofile.config.inject.ConfigProperty; - -import java.util.ArrayList; -import java.util.List; - -import static com.mongodb.client.model.Filters.eq; - -@ApplicationScoped -public class PokemongRepository { - - // FIXME? or suppress warning: "Unsatisfied dependency: no bean matches the injection point" - @Inject - MongoClient mongoClient; - - @ConfigProperty(name = "quarkus.mongodb.database") - String DB_NAME; - - private MongoCollection getCollection() { - MongoDatabase db = mongoClient.getDatabase(DB_NAME); - return db.getCollection(Pokemong.COLLECTION_NAME, Pokemong.class); - } - - public Pokemong findById(String id) { - return getCollection().find(eq("_id", new ObjectId(id))) - .first(); - } - - public void persist(Pokemong pokemong) { - getCollection().insertOne(pokemong); - } - - public List listAll() { - return getCollection().find() - .into(new ArrayList<>()); - } - - public void delete(Pokemong pokemong) { - getCollection().deleteOne(eq("_id", new ObjectId(pokemong.getId()))); - } - - public void persistOrUpdate(Pokemong pokemong) { - getCollection().replaceOne( - eq("_id", new ObjectId(pokemong.getId())), - pokemong, - new ReplaceOptions().upsert(true) - ); - } -} +package fr.uca.iut.repositories; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import fr.uca.iut.entities.Pokemong; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import org.bson.conversions.Bson; +import org.bson.types.ObjectId; + +import java.util.ArrayList; +import java.util.List; + +@ApplicationScoped +public class PokemongRepository extends GenericRepository { + + // FIX?ME + /** + * Warns that "Unsatisfied dependency: no bean matches the injection point" + * but the app works + */ + @Inject + MongoClient mongoClient; + + @PostConstruct + public void init() { + setMongoClient(mongoClient); + } + + public List findByMove(String moveId) { + Bson filter = Filters.elemMatch("moveSet", Filters.eq("_id", new ObjectId(moveId))); + return getCollection().find(filter) + .into(new ArrayList<>()); + } + + @Override + protected MongoCollection getCollection() { + MongoDatabase db = mongoClient.getDatabase(DB_NAME); + return db.getCollection(Pokemong.COLLECTION_NAME, Pokemong.class); + } + +} diff --git a/src/main/java/fr/uca/iut/repositories/TrainerRepository.java b/src/main/java/fr/uca/iut/repositories/TrainerRepository.java new file mode 100644 index 0000000..35ff7ed --- /dev/null +++ b/src/main/java/fr/uca/iut/repositories/TrainerRepository.java @@ -0,0 +1,32 @@ +package fr.uca.iut.repositories; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import fr.uca.iut.entities.Trainer; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class TrainerRepository extends GenericRepository { + + // FIX?ME + /** + * Warns that "Unsatisfied dependency: no bean matches the injection point" + * but the app works + */ + @Inject + MongoClient mongoClient; + + @PostConstruct + public void init() { + setMongoClient(mongoClient); + } + + @Override + protected MongoCollection getCollection() { + MongoDatabase db = mongoClient.getDatabase(DB_NAME); + return db.getCollection(Trainer.COLLECTION_NAME, Trainer.class); + } +} diff --git a/src/main/java/fr/uca/iut/services/GenericService.java b/src/main/java/fr/uca/iut/services/GenericService.java new file mode 100644 index 0000000..3bd1435 --- /dev/null +++ b/src/main/java/fr/uca/iut/services/GenericService.java @@ -0,0 +1,51 @@ +package fr.uca.iut.services; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.GenericEntity; +import fr.uca.iut.repositories.GenericRepository; +import fr.uca.iut.utils.exceptions.NonValidEntityException; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class GenericService { + + protected GenericRepository repository; + + public void setRepository(GenericRepository repository) { + this.repository = repository; + } + + public T addOne(@NotNull T entity) { + repository.persist(entity); + return entity; + } + + @Nullable + public T getOneById(String id) { + return repository.findById(id); + } + + public List getAll() { + return repository.listAll(); + } + + public void deleteOneById(String id) { + T entity = repository.findById(id); + if (entity != null) { + repository.delete(entity); + } + } + + @Nullable + public abstract T updateOne(@NotNull T entity); + + /** + * Override me and start with `super.validateOne(entity);` + */ + public void validateOne(T entity) { + if (entity == null) { + throw new NonValidEntityException("entity was null"); + } + } +} diff --git a/src/main/java/fr/uca/iut/services/MoveService.java b/src/main/java/fr/uca/iut/services/MoveService.java new file mode 100644 index 0000000..ed30c0e --- /dev/null +++ b/src/main/java/fr/uca/iut/services/MoveService.java @@ -0,0 +1,100 @@ +package fr.uca.iut.services; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.Move; +import fr.uca.iut.entities.Pokemong; +import fr.uca.iut.repositories.MoveRepository; +import fr.uca.iut.utils.StringUtils; +import fr.uca.iut.utils.exceptions.NonValidEntityException; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +@ApplicationScoped +public class MoveService extends GenericService { + + @Inject + MoveRepository moveRepository; + @Inject + PokemongService pokemongService; + + @PostConstruct + public void init() { + setRepository(moveRepository); + } + + @Override + public void deleteOneById(String id) { + super.deleteOneById(id); + List pokemongs = pokemongService.findByMove(id); + for (Pokemong pokemong : pokemongs) { + pokemong.removeMove(id); + pokemongService.updateOne(pokemong); + } + } + + @Override + @Nullable + public Move updateOne(@NotNull Move move) { + Move existingMove = moveRepository.findById(move.getId()); + if (existingMove != null) { + if (!existingMove.getName() + .equals(move.getName())) + { + existingMove.setName(move.getName()); + List pokemongs = pokemongService.findByMove(move.getId()); + for (Pokemong pokemong : pokemongs) { + pokemong.updateMove(move.getId(), move.getName()); + pokemongService.updateOne(pokemong); + } + } + + existingMove.setPower(move.getPower()); + existingMove.setCategory(move.getCategory()); + existingMove.setAccuracy(move.getAccuracy()); + existingMove.setType(move.getType()); + moveRepository.persistOrUpdate(existingMove); + } + return existingMove; + } + + @Override + public void validateOne(Move move) { + + super.validateOne(move); + + List errors = new ArrayList<>(); + + if (StringUtils.isBlankStringOrNull(move.getName())) { + errors.add("move name was null, blank or empty"); + } + + if (move.getPower() == null || move.getPower() < 0) { + errors.add("move power was null or negative"); + } + + if (move.getCategory() == null) { + errors.add("move category was null or invalid"); + } + + if (move.getAccuracy() == null || move.getAccuracy() < 0) { + errors.add("move accuracy was null or negative"); + } + + if (move.getType() == null) { + errors.add("move type was null or invalid"); + } + + if (!errors.isEmpty()) { + throw new NonValidEntityException("Validation errors: " + String.join(", ", errors)); + } + } + + public boolean existsById(String moveId) { + return moveRepository.existsById(moveId); + } +} diff --git a/src/main/java/fr/uca/iut/services/PokemongService.java b/src/main/java/fr/uca/iut/services/PokemongService.java index b7d47a5..ae9afd9 100644 --- a/src/main/java/fr/uca/iut/services/PokemongService.java +++ b/src/main/java/fr/uca/iut/services/PokemongService.java @@ -1,65 +1,202 @@ -package fr.uca.iut.services; - -import fr.uca.iut.entities.Pokemong; -import fr.uca.iut.repositories.PokemongRepository; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; - -import java.util.List; - -@ApplicationScoped -public class PokemongService { - - @Inject - PokemongRepository pokemongRepository; - - public Pokemong addPokemong(Pokemong pokemong) { - pokemongRepository.persist(pokemong); - return pokemong; - } - - public Pokemong getPokemong(String id) { - return pokemongRepository.findById(id); - } - - public List getAllPokemongs() { - return pokemongRepository.listAll(); - } - - public void deletePokemong(String id) { - Pokemong pokemong = pokemongRepository.findById(id); - if (pokemong != null) { - pokemongRepository.delete(pokemong); - } - } - - public Pokemong updatePokemong(Pokemong pokemong) { - Pokemong existingPokemong = pokemongRepository.findById(pokemong.getId()); - if (existingPokemong != null) { - existingPokemong.setNickname(pokemong.getNickname()); - existingPokemong.setDob(pokemong.getDob()); - existingPokemong.setLevel(pokemong.getLevel()); - existingPokemong.setPokedexId(pokemong.getPokedexId()); - existingPokemong.setEvoStage(pokemong.getEvoStage()); - existingPokemong.setEvoTrack(pokemong.getEvoTrack()); - existingPokemong.setMegaEvolved(pokemong.getMegaEvolved()); - existingPokemong.setTrainer(pokemong.getTrainer()); - existingPokemong.setTypes(pokemong.getTypes()); - existingPokemong.setMoveSet(pokemong.getMoveSet()); - pokemongRepository.persistOrUpdate(existingPokemong); - } - return existingPokemong; - } - - public boolean isNotMature(Pokemong pokemong) { - return pokemong == null - || pokemong.getEvoStage() == null - || pokemong.getEvoTrack() == null - || pokemong.getEvoTrack() - .isEmpty() - || (pokemong.getEvoStage() != pokemong.getEvoTrack() - .size() - 1); - } - - // TODO PATCH ? -} +package fr.uca.iut.services; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.*; +import fr.uca.iut.repositories.PokemongRepository; +import fr.uca.iut.utils.StringUtils; +import fr.uca.iut.utils.enums.PokemongName; +import fr.uca.iut.utils.exceptions.NonValidEntityException; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +@ApplicationScoped +public class PokemongService extends GenericService { + + @Inject + PokemongRepository pokemongRepository; + + @Inject + MoveService moveService; + + @Inject + TrainerService trainerService; + + @PostConstruct + public void init() { + setRepository(pokemongRepository); + } + + @Override + public Pokemong addOne(@NotNull Pokemong pokemong) { + Pokemong persistedPokemong = super.addOne(pokemong); + + Trainer trainer = trainerService.getOneById(pokemong.getTrainer()); + if (trainer != null) { + TrainerPokemong trainerPokemong = new TrainerPokemong(); + trainerPokemong.setId(pokemong.getId()); + trainerPokemong.setNickname(pokemong.getNickname()); + trainerPokemong.setSpecies(pokemong.getSpecies()); + trainer.getPokemongs() + .add(trainerPokemong); + trainerService.updateOne(trainer); + } + return persistedPokemong; + } + + @Override + public void deleteOneById(String id) { + Pokemong pokemong = getOneById(id); + if (pokemong != null && pokemong.getTrainer() != null) { + Trainer trainer = trainerService.getOneById(pokemong.getTrainer()); + if (trainer != null) { + trainer.getPokemongs() + .removeIf(trainerPokemong -> trainerPokemong.getId() + .equals(id)); + trainerService.updateOne(trainer); + } + } + super.deleteOneById(id); + } + + @Override + @Nullable + public Pokemong updateOne(@NotNull Pokemong pokemong) { + Pokemong existingPokemong = pokemongRepository.findById(pokemong.getId()); + if (existingPokemong != null) { + boolean nicknameChanged = !Objects.equals(existingPokemong.getNickname(), pokemong.getNickname()); + boolean evoStageChanged = !Objects.equals(existingPokemong.getEvoStage(), pokemong.getEvoStage()); + boolean evoTrackChanged = !Objects.equals(existingPokemong.getEvoTrack(), pokemong.getEvoTrack()); + + existingPokemong.setNickname(pokemong.getNickname()); + existingPokemong.setDob(pokemong.getDob()); + existingPokemong.setLevel(pokemong.getLevel()); + existingPokemong.setPokedexId(pokemong.getPokedexId()); + existingPokemong.setEvoStage(pokemong.getEvoStage()); + existingPokemong.setEvoTrack(pokemong.getEvoTrack()); + existingPokemong.setTrainer(pokemong.getTrainer()); + existingPokemong.setTypes(pokemong.getTypes()); + existingPokemong.setMoveSet(pokemong.getMoveSet()); + + pokemongRepository.persistOrUpdate(existingPokemong); + + if (nicknameChanged || evoStageChanged || evoTrackChanged) { + Trainer trainer = trainerService.getOneById(existingPokemong.getTrainer()); + if (trainer != null) { + TrainerPokemong trainerPokemong = trainer.getPokemongs() + .stream() + .filter(tp -> tp.getId() + .equals(existingPokemong.getId())) + .findFirst() + .orElse(null); + + if (trainerPokemong != null) { + if (nicknameChanged) { + trainerPokemong.setNickname(existingPokemong.getNickname()); + } + + if (evoStageChanged || evoTrackChanged) { + trainerPokemong.setSpecies(existingPokemong.getSpecies()); + } + + trainerService.updateOne(trainer); + } + } + } + } + return existingPokemong; + } + + @Override + public void validateOne(Pokemong pokemong) { + + super.validateOne(pokemong); + + List errors = new ArrayList<>(); + + if (pokemong.getDob() == null) { + errors.add("pokemong date of birth was null or invalid"); + } + + if (pokemong.getLevel() == null || pokemong.getLevel() < 1) { + errors.add("pokemong level was null or less than 1"); + } + + if (pokemong.getPokedexId() == null || pokemong.getPokedexId() < 1) { + errors.add("pokemong pokedex id was null or less than 1"); + } + + if (pokemong.getEvoStage() == null || pokemong.getEvoStage() < 0) { + errors.add("pokemong evo stage was null or negative"); + } + + if (pokemong.getEvoTrack() == null) { + errors.add("pokemong evo track was null or invalid"); + } + + List types = pokemong.getTypes(); + if (types == null + || types.size() == 0 + || types.size() > 2) + { + errors.add("pokemong types was null or empty or had more than 2 types"); + } + + Set moveSet = pokemong.getMoveSet(); + if (moveSet == null) { + errors.add("pokemong move set was null"); + } + else { + if (moveSet.size() == 0 || moveSet.size() > 4) { + errors.add("pokemong move set was empty or had more than 4 moves"); + } + for (PokemongMove move : moveSet) { + String moveId = move.getId(); + String moveName = move.getName(); + if (StringUtils.isBlankStringOrNull(moveId) || !moveService.existsById(moveId)) { + errors.add("move with id " + moveId + " does not exist"); + } + if (StringUtils.isBlankStringOrNull(moveName)) { + errors.add("move name was null, blank or empty"); + } + // We don't check whether the move name is consistent with the original -- trainers can rename moves + // locally in a pokemong. If once in a while a Move has its name updated, the change will be reflected + // in all the PokemongMoves, and the local aliases will be lost + } + } + + if (!errors.isEmpty()) { + throw new NonValidEntityException("Validation errors: " + String.join(", ", errors)); + } + } + + public List findByMove(String id) { + return pokemongRepository.findByMove(id); + } + + public boolean isEvoValid(String id, PokemongName species) { + Pokemong pokemong = pokemongRepository.findById(id); + + return pokemong != null && pokemong.getSpecies() == species; + } + + public boolean existsById(String pokemongId) { + return repository.existsById(pokemongId); + } + + public void batchUpdatePokemongTrainers(List trainerPokemongs, @Nullable String trainerId) { + for (TrainerPokemong trainerPokemong : trainerPokemongs) { + Pokemong pokemong = getOneById(trainerPokemong.getId()); + if (pokemong != null) { + pokemong.setTrainer(trainerId); + updateOne(pokemong); + } + } + } +} diff --git a/src/main/java/fr/uca/iut/services/TrainerService.java b/src/main/java/fr/uca/iut/services/TrainerService.java new file mode 100644 index 0000000..65d8a88 --- /dev/null +++ b/src/main/java/fr/uca/iut/services/TrainerService.java @@ -0,0 +1,136 @@ +package fr.uca.iut.services; + +import com.mongodb.lang.Nullable; +import fr.uca.iut.entities.Pokemong; +import fr.uca.iut.entities.Trainer; +import fr.uca.iut.entities.TrainerPokemong; +import fr.uca.iut.repositories.TrainerRepository; +import fr.uca.iut.utils.StringUtils; +import fr.uca.iut.utils.exceptions.NonValidEntityException; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +@ApplicationScoped +public class TrainerService extends GenericService { + + @Inject + TrainerRepository trainerRepository; + + @Inject + PokemongService pokemongService; + + @PostConstruct + public void init() { + setRepository(trainerRepository); + } + + @Override + public Trainer addOne(@NotNull Trainer trainer) { + Trainer persistedTrainer = super.addOne(trainer); + + pokemongService.batchUpdatePokemongTrainers(trainer.getPokemongs(), trainer.getId()); + + return persistedTrainer; + } + + @Override + public void deleteOneById(String id) { + Trainer trainer = getOneById(id); + + if (trainer != null) { + pokemongService.batchUpdatePokemongTrainers(trainer.getPokemongs(), null); + } + + super.deleteOneById(id); + } + + @Nullable + @Override + public Trainer updateOne(@NotNull Trainer trainer) { + Trainer existingTrainer = trainerRepository.findById(trainer.getId()); + if (existingTrainer != null) { + existingTrainer.setName(trainer.getName()); + existingTrainer.setDob(trainer.getDob()); + existingTrainer.setWins(trainer.getLosses()); + existingTrainer.setLosses(trainer.getLosses()); + existingTrainer.setPastOpponents(trainer.getPastOpponents()); + existingTrainer.setPokemongs(trainer.getPokemongs()); + trainerRepository.persistOrUpdate(existingTrainer); + } + return existingTrainer; + } + + @Override + public void validateOne(Trainer trainer) { + + super.validateOne(trainer); + + List errors = new ArrayList<>(); + + if (StringUtils.isBlankStringOrNull(trainer.getName())) { + errors.add("trainer name was null, blank or empty"); + } + + if (trainer.getDob() == null) { + errors.add("trainer date of birth was null or invalid"); + } + + if (trainer.getLosses() == null || trainer.getLosses() < 0) { + errors.add("trainer losses was null or negative"); + } + + if (trainer.getWins() == null || trainer.getWins() < 0) { + errors.add("trainer wins was null or negative"); + } + + List pastOpponents = trainer.getPastOpponents(); + + if (pastOpponents == null) { + errors.add("trainer past opponents collection was null"); + } + else { + for (String trainerId : pastOpponents) { + if (StringUtils.isBlankStringOrNull(trainerId) || !trainerRepository.existsById(trainerId)) { + errors.add("trainer past opponents collection contained an invalid or unknown id"); + } + } + } + + List pokemongs = trainer.getPokemongs(); + + if (pokemongs == null) { + errors.add("trainer pokemongs collection was null or invalid"); + } + else { + for (TrainerPokemong pokemong : pokemongs) { + String pokemongId = pokemong.getId(); + if (StringUtils.isBlankStringOrNull(pokemongId) || !pokemongService.existsById(pokemongId)) { + errors.add("pokemong with id " + pokemongId + " does not exist"); + } + else { + if (!pokemongService.isEvoValid(pokemongId, pokemong.getSpecies())) { + errors.add("pokemong with id " + pokemongId + " cannot be a " + + pokemong.getSpecies()); + } + Pokemong pokemongBehind = pokemongService.getOneById(pokemongId); + if (pokemong.getNickname() != null + && pokemongBehind != null + && !pokemong.getNickname() + .equals(pokemongBehind.getNickname())) + { + errors.add("pokemong with id " + pokemongId + " already has a nickname"); + } + } + } + } + + if (!errors.isEmpty()) { + throw new NonValidEntityException("Validation errors: " + String.join(", ", errors)); + } + } +} diff --git a/src/main/java/fr/uca/iut/utils/StringUtils.java b/src/main/java/fr/uca/iut/utils/StringUtils.java new file mode 100644 index 0000000..453af77 --- /dev/null +++ b/src/main/java/fr/uca/iut/utils/StringUtils.java @@ -0,0 +1,7 @@ +package fr.uca.iut.utils; + +public class StringUtils { + public static boolean isBlankStringOrNull(String string) { + return string == null || string.isBlank(); + } +} diff --git a/src/main/java/fr/uca/iut/utils/enums/MoveCategoryName.java b/src/main/java/fr/uca/iut/utils/enums/MoveCategoryName.java new file mode 100644 index 0000000..dd1466c --- /dev/null +++ b/src/main/java/fr/uca/iut/utils/enums/MoveCategoryName.java @@ -0,0 +1,7 @@ +package fr.uca.iut.utils.enums; + +public enum MoveCategoryName { + PHYSICAL, + SPECIAL, + STATUS +} diff --git a/src/main/java/fr/uca/iut/utils/PokemongName.java b/src/main/java/fr/uca/iut/utils/enums/PokemongName.java similarity index 99% rename from src/main/java/fr/uca/iut/utils/PokemongName.java rename to src/main/java/fr/uca/iut/utils/enums/PokemongName.java index dcd0723..a6296c0 100644 --- a/src/main/java/fr/uca/iut/utils/PokemongName.java +++ b/src/main/java/fr/uca/iut/utils/enums/PokemongName.java @@ -1,4 +1,4 @@ -package fr.uca.iut.utils; +package fr.uca.iut.utils.enums; public enum PokemongName { BULBASAUR, diff --git a/src/main/java/fr/uca/iut/utils/TypeName.java b/src/main/java/fr/uca/iut/utils/enums/TypeName.java similarity index 87% rename from src/main/java/fr/uca/iut/utils/TypeName.java rename to src/main/java/fr/uca/iut/utils/enums/TypeName.java index 3383d2d..757b1c6 100644 --- a/src/main/java/fr/uca/iut/utils/TypeName.java +++ b/src/main/java/fr/uca/iut/utils/enums/TypeName.java @@ -1,4 +1,4 @@ -package fr.uca.iut.utils; +package fr.uca.iut.utils.enums; public enum TypeName { NORMAL, diff --git a/src/main/java/fr/uca/iut/utils/exceptions/NonValidEntityException.java b/src/main/java/fr/uca/iut/utils/exceptions/NonValidEntityException.java new file mode 100644 index 0000000..2d0bf42 --- /dev/null +++ b/src/main/java/fr/uca/iut/utils/exceptions/NonValidEntityException.java @@ -0,0 +1,7 @@ +package fr.uca.iut.utils.exceptions; + +public class NonValidEntityException extends RuntimeException { + public NonValidEntityException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/openapi.yaml b/src/main/resources/META-INF/openapi.yaml new file mode 100644 index 0000000..b3192f0 --- /dev/null +++ b/src/main/resources/META-INF/openapi.yaml @@ -0,0 +1,1748 @@ +openapi: "3.0.3" +info: + title: "Pokemong API" + description: "Pokemong API" + version: "1.0.0" +servers: + - url: "http://localhost:8080" + +paths: + + /pokemong/{id}: + + get: + summary: Get a Pokemong by ID + parameters: + - name: id + in: path + required: true + description: The ID of the Pokemong + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Pokemong' + '400': + description: Invalid ID format + '404': + description: Entity not found for given ID + + put: + summary: Update a Pokemong by ID + parameters: + - name: id + in: path + required: true + description: The ID of the Pokemong + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Pokemong' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Pokemong' + '400': + description: Invalid ID format or Non-valid entity + '404': + description: Entity not found for given ID + + delete: + summary: Delete a Pokemong by ID + parameters: + - name: id + in: path + required: true + description: The ID of the Pokemong + schema: + type: string + responses: + '200': + description: OK + '400': + description: Invalid ID format + + /pokemong: + + get: + summary: Get all Pokemongs + responses: + '200': + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pokemong' + + post: + summary: Create a new Pokemong + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Pokemong' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/Pokemong' + '400': + description: Non-valid entity + + /move/{id}: + + get: + summary: Get a move by ID + parameters: + - name: id + in: path + required: true + description: The ID of the move + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Move' + '400': + description: Invalid ID format + '404': + description: Entity not found for given ID + + put: + summary: Update a move by ID + parameters: + - name: id + in: path + required: true + description: The ID of the move + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Move' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Move' + '400': + description: Invalid ID format or Non-valid entity + '404': + description: Entity not found for given ID + + delete: + summary: Delete a move by ID + parameters: + - name: id + in: path + required: true + description: The ID of the move + schema: + type: string + responses: + '200': + description: OK + '400': + description: Invalid ID format + + /move: + + get: + summary: Get all moves + responses: + '200': + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Move' + + post: + summary: Create a new move + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Move' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/Move' + '400': + description: Non-valid entity + + /trainer: + + get: + summary: Returns a list of all trainers + responses: + '200': + description: A list of trainers + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Trainer' + + post: + summary: Creates a new trainer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + responses: + '201': + description: The created trainer + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + '400': + description: Bad request - invalid trainer data + + /trainer/{id}: + + get: + summary: Returns a trainer by ID + parameters: + - in: path + name: id + required: true + schema: + type: string + responses: + '200': + description: A single trainer + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + '404': + description: Trainer not found + + put: + summary: Updates a trainer by ID + parameters: + - in: path + name: id + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + responses: + '200': + description: The updated trainer + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + '400': + description: Bad request - invalid trainer data + '404': + description: Trainer not found + + delete: + summary: Deletes a trainer by ID + parameters: + - in: path + name: id + required: true + schema: + type: string + responses: + '200': + description: Trainer successfully deleted + '400': + description: Bad request - invalid trainer ID + '404': + description: Trainer not found + +components: + + schemas: + + Pokemong: + type: object + required: + - dob + - level + - pokedexId + - evoStage + - evoTrack + - types + - moveSet + properties: + nickname: + type: string + nullable: true + dob: + type: string + format: date + level: + type: integer + minimum: 1 + pokedexId: + type: integer + minimum: 1 + evoStage: + type: integer + minimum: 0 + evoTrack: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/PokemongName' + trainer: + type: string + description: MongoDB ObjectId referencing a document in a collection + nullable: true + types: + type: array + minItems: 1 + maxItems: 2 + items: + $ref: '#/components/schemas/TypeName' + moveSet: + type: array + minItems: 1 + maxItems: 4 + items: + $ref: '#/components/schemas/PokemongMove' + + Move: + type: object + required: + - name + - power + - category + - accuracy + - type + properties: + name: + type: string + minLength: 1 + category: + $ref: '#/components/schemas/MoveCategoryName' + power: + type: integer + minimum: 0 + accuracy: + type: integer + minimum: 0 + type: + $ref: '#/components/schemas/TypeName' + + Trainer: + type: object + required: + - name + - dob + - wins + - losses + - pastOpponents + - pokemongs + properties: + name: + type: string + minLength: 1 + dob: + type: string + format: date + wins: + type: integer + minimum: 0 + losses: + type: integer + minimum: 0 + pastOpponents: + type: array + items: + type: string + minLength: 1 + pokemongs: + type: array + items: + $ref: '#/components/schemas/TrainerPokemong' + + PokemongMove: + type: object + required: + - id + - name + properties: + id: + type: string + minLength: 1 + name: + type: string + minLength: 1 + + TrainerPokemong: + type: object + required: + - id + - species + properties: + id: + type: string + minLength: 1 + nickname: + type: string + nullable: true + species: + $ref: '#/components/schemas/PokemongName' + + MoveCategoryName: + type: string + enum: [ + PHYSICAL, + SPECIAL, + STATUS ] + + TypeName: + type: string + enum: [ + NORMAL, + GRASS, + ELECTRIC, + WATER, + FIRE, + BUG, + GHOST, + PSYCHIC, + STEEL, + DARK, + FLYING, + ICE, + POISON, + GROUND, + ROCK, + DRAGON, + FIGHTING, + FAIRY + ] + + PokemongName: + type: string + enum: [ + BULBASAUR, + IVYSAUR, + VENUSAUR, + CHARMANDER, + CHARMELEON, + CHARIZARD, + SQUIRTLE, + WARTORTLE, + BLASTOISE, + CATERPIE, + METAPOD, + BUTTERFREE, + WEEDLE, + KAKUNA, + BEEDRILL, + PIDGEY, + PIDGEOTTO, + PIDGEOT, + RATTATA, + RATICATE, + SPEAROW, + FEAROW, + EKANS, + ARBOK, + PIKACHU, + RAICHU, + SANDSHREW, + SANDSLASH, + NIDORAN_F, + NIDORINA, + NIDOQUEEN, + NIDORAN_M, + NIDORINO, + NIDOKING, + CLEFAIRY, + CLEFABLE, + VULPIX, + NINETALES, + JIGGLYPUFF, + WIGGLYTUFF, + ZUBAT, + GOLBAT, + ODDISH, + GLOOM, + VILEPLUME, + PARAS, + PARASECT, + VENONAT, + VENOMOTH, + DIGLETT, + DUGTRIO, + MEOWTH, + PERSIAN, + PSYDUCK, + GOLDUCK, + MANKEY, + PRIMEAPE, + GROWLITHE, + ARCANINE, + POLIWAG, + POLIWHIRL, + POLIWRATH, + ABRA, + KADABRA, + ALAKAZAM, + MACHOP, + MACHOKE, + MACHAMP, + BELLSPROUT, + WEEPINBELL, + VICTREEBEL, + TENTACOOL, + TENTACRUEL, + GEODUDE, + GRAVELER, + GOLEM, + PONYTA, + RAPIDASH, + SLOWPOKE, + SLOWBRO, + MAGNEMITE, + MAGNETON, + FARFETCHD, + DODUO, + DODRIO, + SEEL, + DEWGONG, + GRIMER, + MUK, + SHELLDER, + CLOYSTER, + GASTLY, + HAUNTER, + GENGAR, + ONIX, + DROWZEE, + HYPNO, + KRABBY, + KINGLER, + VOLTORB, + ELECTRODE, + EXEGGCUTE, + EXEGGUTOR, + CUBONE, + MAROWAK, + HITMONLEE, + HITMONCHAN, + LICKITUNG, + KOFFING, + WEEZING, + RHYHORN, + RHYDON, + CHANSEY, + TANGELA, + KANGASKHAN, + HORSEA, + SEADRA, + GOLDEEN, + SEAKING, + STARYU, + STARMIE, + MR_MIME, + SCYTHER, + JYNX, + ELECTABUZZ, + MAGMAR, + PINSIR, + TAUROS, + MAGIKARP, + GYARADOS, + LAPRAS, + DITTO, + EEVEE, + VAPOREON, + JOLTEON, + FLAREON, + PORYGON, + OMANYTE, + OMASTAR, + KABUTO, + KABUTOPS, + AERODACTYL, + SNORLAX, + ARTICUNO, + ZAPDOS, + MOLTRES, + DRATINI, + DRAGONAIR, + DRAGONITE, + MEWTWO, + MEW, + CHIKORITA, + BAYLEEF, + MEGANIUM, + CYNDAQUIL, + QUILAVA, + TYPHLOSION, + TOTODILE, + CROCONAW, + FERALIGATR, + SENTRET, + FURRET, + HOOTHOOT, + NOCTOWL, + LEDYBA, + LEDIAN, + SPINARAK, + ARIADOS, + CROBAT, + CHINCHOU, + LANTURN, + PICHU, + CLEFFA, + IGGLYBUFF, + TOGEPI, + TOGETIC, + NATU, + XATU, + MAREEP, + FLAAFFY, + AMPHAROS, + BELLOSSOM, + MARILL, + AZUMARILL, + SUDOWOODO, + POLITOED, + HOPPIP, + SKIPLOOM, + JUMPLUFF, + AIPOM, + SUNKERN, + SUNFLORA, + YANMA, + WOOPER, + QUAGSIRE, + ESPEON, + UMBREON, + MURKROW, + SLOWKING, + MISDREAVUS, + UNOWN, + WOBBUFFET, + GIRAFARIG, + PINECO, + FORRETRESS, + DUNSPARCE, + GLIGAR, + STEELIX, + SNUBBULL, + GRANBULL, + QWILFISH, + SCIZOR, + SHUCKLE, + HERACROSS, + SNEASEL, + TEDDIURSA, + URSARING, + SLUGMA, + MAGCARGO, + SWINUB, + PILOSWINE, + CORSOLA, + REMORAID, + OCTILLERY, + DELIBIRD, + MANTINE, + SKARMORY, + HOUNDOUR, + HOUNDOOM, + KINGDRA, + PHANPY, + DONPHAN, + PORYGON2, + STANTLER, + SMEARGLE, + TYROGUE, + HITMONTOP, + SMOOCHUM, + ELEKID, + MAGBY, + MILTANK, + BLISSEY, + RAIKOU, + ENTEI, + SUICUNE, + LARVITAR, + PUPITAR, + TYRANITAR, + LUGIA, + HO_OH, + CELEBI, + TREECKO, + GROVYLE, + SCEPTILE, + TORCHIC, + COMBUSKEN, + BLAZIKEN, + MUDKIP, + MARSHTOMP, + SWAMPERT, + POOCHYENA, + MIGHTYENA, + ZIGZAGOON, + LINOONE, + WURMPLE, + SILCOON, + BEAUTIFLY, + CASCOON, + DUSTOX, + LOTAD, + LOMBRE, + LUDICOLO, + SEEDOT, + NUZLEAF, + SHIFTRY, + TAILLOW, + SWELLOW, + WINGULL, + PELIPPER, + RALTS, + KIRLIA, + GARDEVOIR, + SURSKIT, + MASQUERAIN, + SHROOMISH, + BRELOOM, + SLAKOTH, + VIGOROTH, + SLAKING, + NINCADA, + NINJASK, + SHEDINJA, + WHISMUR, + LOUDRED, + EXPLOUD, + MAKUHITA, + HARIYAMA, + AZURILL, + NOSEPASS, + SKITTY, + DELCATTY, + SABLEYE, + MAWILE, + ARON, + LAIRON, + AGGRON, + MEDITITE, + MEDICHAM, + ELECTRIKE, + MANECTRIC, + PLUSLE, + MINUN, + VOLBEAT, + ILLUMISE, + ROSELIA, + GULPIN, + SWALOT, + CARVANHA, + SHARPEDO, + WAILMER, + WAILORD, + NUMEL, + CAMERUPT, + TORKOAL, + SPOINK, + GRUMPIG, + SPINDA, + TRAPINCH, + VIBRAVA, + FLYGON, + CACNEA, + CACTURNE, + SWABLU, + ALTARIA, + ZANGOOSE, + SEVIPER, + LUNATONE, + SOLROCK, + BARBOACH, + WHISCASH, + CORPHISH, + CRAWDAUNT, + BALTOY, + CLAYDOL, + LILEEP, + CRADILY, + ANORITH, + ARMALDO, + FEEBAS, + MILOTIC, + CASTFORM, + KECLEON, + SHUPPET, + BANETTE, + DUSKULL, + DUSCLOPS, + TROPIUS, + CHIMECHO, + ABSOL, + WYNAUT, + SNORUNT, + GLALIE, + SPHEAL, + SEALEO, + WALREIN, + CLAMPERL, + HUNTAIL, + GOREBYSS, + RELICANTH, + LUVDISC, + BAGON, + SHELGON, + SALAMENCE, + BELDUM, + METANG, + METAGROSS, + REGIROCK, + REGICE, + REGISTEEL, + LATIAS, + LATIOS, + KYOGRE, + GROUDON, + RAYQUAZA, + JIRACHI, + DEOXYS_NORMAL, + TURTWIG, + GROTLE, + TORTERRA, + CHIMCHAR, + MONFERNO, + INFERNAPE, + PIPLUP, + PRINPLUP, + EMPOLEON, + STARLY, + STARAVIA, + STARAPTOR, + BIDOOF, + BIBAREL, + KRICKETOT, + KRICKETUNE, + SHINX, + LUXIO, + LUXRAY, + BUDEW, + ROSERADE, + CRANIDOS, + RAMPARDOS, + SHIELDON, + BASTIODON, + BURMY, + WORMADAM_PLANT, + MOTHIM, + COMBEE, + VESPIQUEN, + PACHIRISU, + BUIZEL, + FLOATZEL, + CHERUBI, + CHERRIM, + SHELLOS, + GASTRODON, + AMBIPOM, + DRIFLOON, + DRIFBLIM, + BUNEARY, + LOPUNNY, + MISMAGIUS, + HONCHKROW, + GLAMEOW, + PURUGLY, + CHINGLING, + STUNKY, + SKUNTANK, + BRONZOR, + BRONZONG, + BONSLY, + MIME_JR, + HAPPINY, + CHATOT, + SPIRITOMB, + GIBLE, + GABITE, + GARCHOMP, + MUNCHLAX, + RIOLU, + LUCARIO, + HIPPOPOTAS, + HIPPOWDON, + SKORUPI, + DRAPION, + CROAGUNK, + TOXICROAK, + CARNIVINE, + FINNEON, + LUMINEON, + MANTYKE, + SNOVER, + ABOMASNOW, + WEAVILE, + MAGNEZONE, + LICKILICKY, + RHYPERIOR, + TANGROWTH, + ELECTIVIRE, + MAGMORTAR, + TOGEKISS, + YANMEGA, + LEAFEON, + GLACEON, + GLISCOR, + MAMOSWINE, + PORYGON_Z, + GALLADE, + PROBOPASS, + DUSKNOIR, + FROSLASS, + ROTOM, + UXIE, + MESPRIT, + AZELF, + DIALGA, + PALKIA, + HEATRAN, + REGIGIGAS, + GIRATINA_ALTERED, + CRESSELIA, + PHIONE, + MANAPHY, + DARKRAI, + SHAYMIN_LAND, + ARCEUS, + VICTINI, + SNIVY, + SERVINE, + SERPERIOR, + TEPIG, + PIGNITE, + EMBOAR, + OSHAWOTT, + DEWOTT, + SAMUROTT, + PATRAT, + WATCHOG, + LILLIPUP, + HERDIER, + STOUTLAND, + PURRLOIN, + LIEPARD, + PANSAGE, + SIMISAGE, + PANSEAR, + SIMISEAR, + PANPOUR, + SIMIPOUR, + MUNNA, + MUSHARNA, + PIDOVE, + TRANQUILL, + UNFEZANT, + BLITZLE, + ZEBSTRIKA, + ROGGENROLA, + BOLDORE, + GIGALITH, + WOOBAT, + SWOOBAT, + DRILBUR, + EXCADRILL, + AUDINO, + TIMBURR, + GURDURR, + CONKELDURR, + TYMPOLE, + PALPITOAD, + SEISMITOAD, + THROH, + SAWK, + SEWADDLE, + SWADLOON, + LEAVANNY, + VENIPEDE, + WHIRLIPEDE, + SCOLIPEDE, + COTTONEE, + WHIMSICOTT, + PETILIL, + LILLIGANT, + BASCULIN_RED_STRIPED, + SANDILE, + KROKOROK, + KROOKODILE, + DARUMAKA, + DARMANITAN_STANDARD, + MARACTUS, + DWEBBLE, + CRUSTLE, + SCRAGGY, + SCRAFTY, + SIGILYPH, + YAMASK, + COFAGRIGUS, + TIRTOUGA, + CARRACOSTA, + ARCHEN, + ARCHEOPS, + TRUBBISH, + GARBODOR, + ZORUA, + ZOROARK, + MINCCINO, + CINCCINO, + GOTHITA, + GOTHORITA, + GOTHITELLE, + SOLOSIS, + DUOSION, + REUNICLUS, + DUCKLETT, + SWANNA, + VANILLITE, + VANILLISH, + VANILLUXE, + DEERLING, + SAWSBUCK, + EMOLGA, + KARRABLAST, + ESCAVALIER, + FOONGUS, + AMOONGUSS, + FRILLISH, + JELLICENT, + ALOMOMOLA, + JOLTIK, + GALVANTULA, + FERROSEED, + FERROTHORN, + KLINK, + KLANG, + KLINKLANG, + TYNAMO, + EELEKTRIK, + EELEKTROSS, + ELGYEM, + BEHEEYEM, + LITWICK, + LAMPENT, + CHANDELURE, + AXEW, + FRAXURE, + HAXORUS, + CUBCHOO, + BEARTIC, + CRYOGONAL, + SHELMET, + ACCELGOR, + STUNFISK, + MIENFOO, + MIENSHAO, + DRUDDIGON, + GOLETT, + GOLURK, + PAWNIARD, + BISHARP, + BOUFFALANT, + RUFFLET, + BRAVIARY, + VULLABY, + MANDIBUZZ, + HEATMOR, + DURANT, + DEINO, + ZWEILOUS, + HYDREIGON, + LARVESTA, + VOLCARONA, + COBALION, + TERRAKION, + VIRIZION, + TORNADUS_INCARNATE, + THUNDURUS_INCARNATE, + RESHIRAM, + ZEKROM, + LANDORUS_INCARNATE, + KYUREM, + KELDEO_ORDINARY, + MELOETTA_ARIA, + GENESECT, + CHESPIN, + QUILLADIN, + CHESNAUGHT, + FENNEKIN, + BRAIXEN, + DELPHOX, + FROAKIE, + FROGADIER, + GRENINJA, + BUNNELBY, + DIGGERSBY, + FLETCHLING, + FLETCHINDER, + TALONFLAME, + SCATTERBUG, + SPEWPA, + VIVILLON, + LITLEO, + PYROAR, + FLABEBE, + FLOETTE, + FLORGES, + SKIDDO, + GOGOAT, + PANCHAM, + PANGORO, + FURFROU, + ESPURR, + MEOWSTIC_MALE, + HONEDGE, + DOUBLADE, + AEGISLASH_SHIELD, + SPRITZEE, + AROMATISSE, + SWIRLIX, + SLURPUFF, + INKAY, + MALAMAR, + BINACLE, + BARBARACLE, + SKRELP, + DRAGALGE, + CLAUNCHER, + CLAWITZER, + HELIOPTILE, + HELIOLISK, + TYRUNT, + TYRANTRUM, + AMAURA, + AURORUS, + SYLVEON, + HAWLUCHA, + DEDENNE, + CARBINK, + GOOMY, + SLIGGOO, + GOODRA, + KLEFKI, + PHANTUMP, + TREVENANT, + PUMPKABOO_AVERAGE, + GOURGEIST_AVERAGE, + BERGMITE, + AVALUGG, + NOIBAT, + NOIVERN, + XERNEAS, + YVELTAL, + ZYGARDE_50, + DIANCIE, + HOOPA, + VOLCANION, + ROWLET, + DARTRIX, + DECIDUEYE, + LITTEN, + TORRACAT, + INCINEROAR, + POPPLIO, + BRIONNE, + PRIMARINA, + PIKIPEK, + TRUMBEAK, + TOUCANNON, + YUNGOOS, + GUMSHOOS, + GRUBBIN, + CHARJABUG, + VIKAVOLT, + CRABRAWLER, + CRABOMINABLE, + ORICORIO_BAILE, + CUTIEFLY, + RIBOMBEE, + ROCKRUFF, + LYCANROC_MIDDAY, + WISHIWASHI_SOLO, + MAREANIE, + TOXAPEX, + MUDBRAY, + MUDSDALE, + DEWPIDER, + ARAQUANID, + FOMANTIS, + LURANTIS, + MORELULL, + SHIINOTIC, + SALANDIT, + SALAZZLE, + STUFFUL, + BEWEAR, + BOUNSWEET, + STEENEE, + TSAREENA, + COMFEY, + ORANGURU, + PASSIMIAN, + WIMPOD, + GOLISOPOD, + SANDYGAST, + PALOSSAND, + PYUKUMUKU, + TYPE_NULL, + SILVALLY, + MINIOR_RED_METEOR, + KOMALA, + TURTONATOR, + TOGEDEMARU, + MIMIKYU_DISGUISED, + BRUXISH, + DRAMPA, + DHELMISE, + JANGMO_O, + HAKAMO_O, + KOMMO_O, + TAPU_KOKO, + TAPU_LELE, + TAPU_BULU, + TAPU_FINI, + COSMOG, + COSMOEM, + SOLGALEO, + LUNALA, + NIHILEGO, + BUZZWOLE, + PHEROMOSA, + XURKITREE, + CELESTEELA, + KARTANA, + GUZZLORD, + NECROZMA, + MAGEARNA, + MARSHADOW, + POIPOLE, + NAGANADEL, + STAKATAKA, + BLACEPHALON, + ZERAORA, + MELTAN, + MELMETAL, + GROOKEY, + THWACKEY, + RILLABOOM, + SCORBUNNY, + RABOOT, + CINDERACE, + SOBBLE, + DRIZZILE, + INTELEON, + SKWOVET, + GREEDENT, + ROOKIDEE, + CORVISQUIRE, + CORVIKNIGHT, + BLIPBUG, + DOTTLER, + ORBEETLE, + NICKIT, + THIEVUL, + GOSSIFLEUR, + ELDEGOSS, + WOOLOO, + DUBWOOL, + CHEWTLE, + DREDNAW, + YAMPER, + BOLTUND, + ROLYCOLY, + CARKOL, + COALOSSAL, + APPLIN, + FLAPPLE, + APPLETUN, + SILICOBRA, + SANDACONDA, + CRAMORANT, + ARROKUDA, + BARRASKEWDA, + TOXEL, + TOXTRICITY_AMPED, + SIZZLIPEDE, + CENTISKORCH, + CLOBBOPUS, + GRAPPLOCT, + SINISTEA, + POLTEAGEIST, + HATENNA, + HATTREM, + HATTERENE, + IMPIDIMP, + MORGREM, + GRIMMSNARL, + OBSTAGOON, + PERRSERKER, + CURSOLA, + SIRFETCHD, + MR_RIME, + RUNERIGUS, + MILCERY, + ALCREMIE, + FALINKS, + PINCURCHIN, + SNOM, + FROSMOTH, + STONJOURNER, + EISCUE_ICE, + INDEEDEE_MALE, + MORPEKO_FULL_BELLY, + CUFANT, + COPPERAJAH, + DRACOZOLT, + ARCTOZOLT, + DRACOVISH, + ARCTOVISH, + DURALUDON, + DREEPY, + DRAKLOAK, + DRAGAPULT, + ZACIAN, + ZAMAZENTA, + ETERNATUS, + KUBFU, + URSHIFU_SINGLE_STRIKE, + ZARUDE, + REGIELEKI, + REGIDRAGO, + GLASTRIER, + SPECTRIER, + CALYREX, + WYRDEER, + KLEAVOR, + URSALUNA, + BASCULEGION_MALE, + SNEASLER, + OVERQWIL, + ENAMORUS_INCARNATE, + SPRIGATITO, + FLORAGATO, + MEOWSCARADA, + FUECOCO, + CROCALOR, + SKELEDIRGE, + QUAXLY, + QUAXWELL, + QUAQUAVAL, + LECHONK, + OINKOLOGNE, + TAROUNTULA, + SPIDOPS, + NYMBLE, + LOKIX, + PAWMI, + PAWMO, + PAWMOT, + TANDEMAUS, + MAUSHOLD, + FIDOUGH, + DACHSBUN, + SMOLIV, + DOLLIV, + ARBOLIVA, + SQUAWKABILLY, + NACLI, + NACLSTACK, + GARGANACL, + CHARCADET, + ARMAROUGE, + CERULEDGE, + TADBULB, + BELLIBOLT, + WATTREL, + KILOWATTREL, + MASCHIFF, + MABOSSTIFF, + SHROODLE, + GRAFAIAI, + BRAMBLIN, + BRAMBLEGHAST, + TOEDSCOOL, + TOEDSCRUEL, + KLAWF, + CAPSAKID, + SCOVILLAIN, + RELLOR, + RABSCA, + FLITTLE, + ESPATHRA, + TINKATINK, + TINKATUFF, + TINKATON, + WIGLETT, + WUGTRIO, + BOMBIRDIER, + FINIZEN, + PALAFIN, + VAROOM, + REVAVROOM, + CYCLIZAR, + ORTHWORM, + GLIMMET, + GLIMMORA, + GREAVARD, + HOUNDSTONE, + FLAMIGO, + CETODDLE, + CETITAN, + VELUZA, + DONDOZO, + TATSUGIRI, + ANNIHILAPE, + CLODSIRE, + FARIGIRAF, + DUDUNSPARCE, + KINGAMBIT, + GREAT_TUSK, + SCREAM_TAIL, + BRUTE_BONNET, + FLUTTER_MANE, + SLITHER_WING, + SANDY_SHOCKS, + IRON_TREADS, + IRON_BUNDLE, + IRON_HANDS, + IRON_JUGULIS, + IRON_MOTH, + IRON_THORNS, + FRIGIBAX, + ARCTIBAX, + BAXCALIBUR, + GIMMIGHOUL, + GHOLDENGO, + WO_CHIEN, + CHIEN_PAO, + TING_LU, + CHI_YU, + ROARING_MOON, + IRON_VALIANT, + KORAIDON, + MIRAIDON, + WALKING_WAKE, + IRON_LEAVES, + DEOXYS_ATTACK, + DEOXYS_DEFENSE, + DEOXYS_SPEED, + WORMADAM_SANDY, + WORMADAM_TRASH, + SHAYMIN_SKY, + GIRATINA_ORIGIN, + ROTOM_HEAT, + ROTOM_WASH, + ROTOM_FROST, + ROTOM_FAN, + ROTOM_MOW, + CASTFORM_SUNNY, + CASTFORM_RAINY, + CASTFORM_SNOWY, + BASCULIN_BLUE_STRIPED, + DARMANITAN_ZEN, + MELOETTA_PIROUETTE, + TORNADUS_THERIAN, + THUNDURUS_THERIAN, + LANDORUS_THERIAN, + KYUREM_BLACK, + KYUREM_WHITE, + KELDEO_RESOLUTE, + MEOWSTIC_FEMALE, + AEGISLASH_BLADE, + PUMPKABOO_SMALL, + PUMPKABOO_LARGE, + PUMPKABOO_SUPER, + GOURGEIST_SMALL, + GOURGEIST_LARGE, + GOURGEIST_SUPER, + VENUSAUR_MEGA, + CHARIZARD_MEGA_X, + CHARIZARD_MEGA_Y, + BLASTOISE_MEGA, + ALAKAZAM_MEGA, + GENGAR_MEGA, + KANGASKHAN_MEGA, + PINSIR_MEGA, + GYARADOS_MEGA, + AERODACTYL_MEGA, + MEWTWO_MEGA_X, + MEWTWO_MEGA_Y, + AMPHAROS_MEGA, + SCIZOR_MEGA, + HERACROSS_MEGA, + HOUNDOOM_MEGA, + TYRANITAR_MEGA, + BLAZIKEN_MEGA, + GARDEVOIR_MEGA, + MAWILE_MEGA, + AGGRON_MEGA, + MEDICHAM_MEGA, + MANECTRIC_MEGA, + BANETTE_MEGA, + ABSOL_MEGA, + GARCHOMP_MEGA, + LUCARIO_MEGA, + ABOMASNOW_MEGA, + FLOETTE_ETERNAL, + LATIAS_MEGA, + LATIOS_MEGA, + SWAMPERT_MEGA, + SCEPTILE_MEGA, + SABLEYE_MEGA, + ALTARIA_MEGA, + GALLADE_MEGA, + AUDINO_MEGA, + SHARPEDO_MEGA, + SLOWBRO_MEGA, + STEELIX_MEGA, + PIDGEOT_MEGA, + GLALIE_MEGA, + DIANCIE_MEGA, + METAGROSS_MEGA, + KYOGRE_PRIMAL, + GROUDON_PRIMAL, + RAYQUAZA_MEGA, + PIKACHU_ROCK_STAR, + PIKACHU_BELLE, + PIKACHU_POP_STAR, + PIKACHU_PHD, + PIKACHU_LIBRE, + PIKACHU_COSPLAY, + HOOPA_UNBOUND, + CAMERUPT_MEGA, + LOPUNNY_MEGA, + SALAMENCE_MEGA, + BEEDRILL_MEGA, + RATTATA_ALOLA, + RATICATE_ALOLA, + RATICATE_TOTEM_ALOLA, + PIKACHU_ORIGINAL_CAP, + PIKACHU_HOENN_CAP, + PIKACHU_SINNOH_CAP, + PIKACHU_UNOVA_CAP, + PIKACHU_KALOS_CAP, + PIKACHU_ALOLA_CAP, + RAICHU_ALOLA, + SANDSHREW_ALOLA, + SANDSLASH_ALOLA, + VULPIX_ALOLA, + NINETALES_ALOLA, + DIGLETT_ALOLA, + DUGTRIO_ALOLA, + MEOWTH_ALOLA, + PERSIAN_ALOLA, + GEODUDE_ALOLA, + GRAVELER_ALOLA, + GOLEM_ALOLA, + GRIMER_ALOLA, + MUK_ALOLA, + EXEGGUTOR_ALOLA, + MAROWAK_ALOLA, + GRENINJA_BATTLE_BOND, + GRENINJA_ASH, + ZYGARDE_10_POWER_CONSTRUCT, + ZYGARDE_50_POWER_CONSTRUCT, + ZYGARDE_COMPLETE, + GUMSHOOS_TOTEM, + VIKAVOLT_TOTEM, + ORICORIO_POM_POM, + ORICORIO_PAU, + ORICORIO_SENSU, + LYCANROC_MIDNIGHT, + WISHIWASHI_SCHOOL, + LURANTIS_TOTEM, + SALAZZLE_TOTEM, + MINIOR_ORANGE_METEOR, + MINIOR_YELLOW_METEOR, + MINIOR_GREEN_METEOR, + MINIOR_BLUE_METEOR, + MINIOR_INDIGO_METEOR, + MINIOR_VIOLET_METEOR, + MINIOR_RED, + MINIOR_ORANGE, + MINIOR_YELLOW, + MINIOR_GREEN, + MINIOR_BLUE, + MINIOR_INDIGO, + MINIOR_VIOLET, + MIMIKYU_BUSTED, + MIMIKYU_TOTEM_DISGUISED, + MIMIKYU_TOTEM_BUSTED, + KOMMO_O_TOTEM, + MAGEARNA_ORIGINAL, + PIKACHU_PARTNER_CAP, + MAROWAK_TOTEM, + RIBOMBEE_TOTEM, + ROCKRUFF_OWN_TEMPO, + LYCANROC_DUSK, + ARAQUANID_TOTEM, + TOGEDEMARU_TOTEM, + NECROZMA_DUSK, + NECROZMA_DAWN, + NECROZMA_ULTRA, + PIKACHU_STARTER, + EEVEE_STARTER, + PIKACHU_WORLD_CAP, + MEOWTH_GALAR, + PONYTA_GALAR, + RAPIDASH_GALAR, + SLOWPOKE_GALAR, + SLOWBRO_GALAR, + FARFETCHD_GALAR, + WEEZING_GALAR, + MR_MIME_GALAR, + ARTICUNO_GALAR, + ZAPDOS_GALAR, + MOLTRES_GALAR, + SLOWKING_GALAR, + CORSOLA_GALAR, + ZIGZAGOON_GALAR, + LINOONE_GALAR, + DARUMAKA_GALAR, + DARMANITAN_GALAR_STANDARD, + DARMANITAN_GALAR_ZEN, + YAMASK_GALAR, + STUNFISK_GALAR, + ZYGARDE_10, + CRAMORANT_GULPING, + CRAMORANT_GORGING, + TOXTRICITY_LOW_KEY, + EISCUE_NOICE, + INDEEDEE_FEMALE, + MORPEKO_HANGRY, + ZACIAN_CROWNED, + ZAMAZENTA_CROWNED, + ETERNATUS_ETERNAMAX, + URSHIFU_RAPID_STRIKE, + ZARUDE_DADA, + CALYREX_ICE, + CALYREX_SHADOW, + VENUSAUR_GMAX, + CHARIZARD_GMAX, + BLASTOISE_GMAX, + BUTTERFREE_GMAX, + PIKACHU_GMAX, + MEOWTH_GMAX, + MACHAMP_GMAX, + GENGAR_GMAX, + KINGLER_GMAX, + LAPRAS_GMAX, + EEVEE_GMAX, + SNORLAX_GMAX, + GARBODOR_GMAX, + MELMETAL_GMAX, + RILLABOOM_GMAX, + CINDERACE_GMAX, + INTELEON_GMAX, + CORVIKNIGHT_GMAX, + ORBEETLE_GMAX, + DREDNAW_GMAX, + COALOSSAL_GMAX, + FLAPPLE_GMAX, + APPLETUN_GMAX, + SANDACONDA_GMAX, + TOXTRICITY_AMPED_GMAX, + CENTISKORCH_GMAX, + HATTERENE_GMAX, + GRIMMSNARL_GMAX, + ALCREMIE_GMAX, + COPPERAJAH_GMAX, + DURALUDON_GMAX, + URSHIFU_SINGLE_STRIKE_GMAX, + URSHIFU_RAPID_STRIKE_GMAX, + TOXTRICITY_LOW_KEY_GMAX, + GROWLITHE_HISUI, + ARCANINE_HISUI, + VOLTORB_HISUI, + ELECTRODE_HISUI, + TYPHLOSION_HISUI, + QWILFISH_HISUI, + SNEASEL_HISUI, + SAMUROTT_HISUI, + LILLIGANT_HISUI, + ZORUA_HISUI, + ZOROARK_HISUI, + BRAVIARY_HISUI, + SLIGGOO_HISUI, + GOODRA_HISUI, + AVALUGG_HISUI, + DECIDUEYE_HISUI, + DIALGA_ORIGIN, + PALKIA_ORIGIN, + BASCULIN_WHITE_STRIPED, + BASCULEGION_FEMALE, + ENAMORUS_THERIAN, + TAUROS_PALDEA_COMBAT_BREED, + TAUROS_PALDEA_BLAZE_BREED, + TAUROS_PALDEA_AQUA_BREED, + WOOPER_PALDEA, + OINKOLOGNE_FEMALE, + DUDUNSPARCE_THREE_SEGMENT, + PALAFIN_HERO, + MAUSHOLD_FAMILY_OF_THREE, + TATSUGIRI_DROOPY, + TATSUGIRI_STRETCHY, + SQUAWKABILLY_BLUE_PLUMAGE, + SQUAWKABILLY_YELLOW_PLUMAGE, + SQUAWKABILLY_WHITE_PLUMAGE, + GIMMIGHOUL_ROAMING, + KORAIDON_LIMITED_BUILD, + KORAIDON_SPRINTING_BUILD, + KORAIDON_SWIMMING_BUILD, + KORAIDON_GLIDING_BUILD, + MIRAIDON_LOW_POWER_MODE, + MIRAIDON_DRIVE_MODE, + MIRAIDON_AQUATIC_MODE, + MIRAIDON_GLIDE_MODE + ] \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6ba7462..008c4b3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,3 @@ -quarkus.mongodb.connection-string=mongodb+srv://:@..mongodb.net -quarkus.mongodb.database= \ No newline at end of file +quarkus.mongodb.connection-string=mongodb+srv://:@..mongodb.net +quarkus.mongodb.database= +quarkus.smallrye-openapi.path=META-INF/openapi.yaml