Correction exercice 3

AddressBookHandler

package fr.imta.addressbook.server.handlers;

import java.util.List;

import fr.imta.addressbook.model.AddressBook;
import fr.imta.addressbook.model.Database;
import fr.imta.addressbook.model.Person;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;

public class AddressBookHandler {
    private Database db;

    public AddressBookHandler(Database db) {
        this.db = db;
    }

    public void getIds(RoutingContext ctx) {
        ctx.json(db.getAddressBooksIds());
    }

    public void getById(RoutingContext ctx) {
        int id = Integer.parseInt(ctx.pathParam("id"));
        AddressBook addressBook = db.getAddressBookById(id);

        if (addressBook == null) {
            ctx.response().setStatusCode(404).end("Address Book not found");
        }
        else {
            ctx.json(addressBook.toJSON());
        }
    }

    public void create(RoutingContext ctx) {
        JsonObject input = ctx.body().asJsonObject();

        AddressBook a = db.createAddressBook(null, List.of());

        if (input.containsKey("owner")) {
            Person owner = db.getPersonById(input.getInteger("owner"));

            if (owner == null) {
                ctx.response().setStatusCode(500);
                ctx.json("error finding owner with id " + input.getInteger("owner"));
                return;
            }

            a.setOwner(owner);
        }
        if (input.containsKey("persons")) {
            JsonArray personsId = input.getJsonArray("persons");
            for (int i = 0; i < personsId.size(); i++) {
                Person p = db.getPersonById(personsId.getInteger(i));
                if (p == null) {
                    ctx.response().setStatusCode(500);
                    ctx.json("error finding person with id " + personsId.getInteger(i));
                    return;
                }
                a.getPersons().add(p);
            }
        }
    }

    public void update(RoutingContext ctx) {
        JsonObject input = ctx.body().asJsonObject();
        int id = Integer.parseInt(ctx.pathParam("id"));
        AddressBook a = db.getAddressBookById(id);

        if (a == null) {
            ctx.response().setStatusCode(404);
            ctx.json("address book not found");
        }
        else {
            if (input.containsKey("owner")) {
                Person owner = db.getPersonById(input.getInteger("owner"));

                if (owner == null) {
                    ctx.response().setStatusCode(500);
                    ctx.json("error finding owner with id " + input.getInteger("owner"));
                    return;
                }
            }
            if (input.containsKey("persons")) {
                JsonArray personsId = input.getJsonArray("persons");
                a.getPersons().clear();
                for (int i = 0; i < personsId.size(); i++) {
                    Person p = db.getPersonById(personsId.getInteger(i));
                    if (p == null) {
                        ctx.response().setStatusCode(500);
                        ctx.json("error finding person with id " + personsId.getInteger(i));
                        return;
                    }
                    a.getPersons().add(p);
                }
            }
            ctx.json("person updated successfully");
        }
    }

    public void delete(RoutingContext ctx) {
        int id = Integer.parseInt(ctx.pathParam("id"));
        AddressBook a = db.getAddressBookById(id);

        if (a == null) {
            ctx.response().setStatusCode(404);
            ctx.json("address book not found");
        }
        else {
            if (db.deleteAddressBook(a)) {
                ctx.json("success");
            }
            else {
                ctx.response().setStatusCode(500);
                ctx.json("error deleting address book " + a.getId());
            }
        }
    }
}

AddressBook

package fr.imta.addressbook.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

public class AddressBook {
    private static int NEXT_ID = 0;
    private int id;

    private Person owner;
    private List<Person> persons;

    public AddressBook(Person owner) {
        this(owner, Collections.emptyList());
    }

    public AddressBook(Person owner, Collection<Person> persons) {
        this.id = NEXT_ID++;
        this.persons = new ArrayList<>(persons);
        setOwner(owner);
    }

    public int getId() {
        return id;
    }

    public Person getOwner() {
        return owner;
    }

    public void setOwner(Person owner) {
        Person previousOwner = this.owner;
        if (owner != this.owner) {
            this.owner = null;
            if (previousOwner != null) {
                previousOwner.setAddressBook(null);
            }
            if (owner != null) {
                this.owner = owner;
                this.owner.setAddressBook(this);
            }
        }
    }

    public List<Person> getPersons() {
        return persons;
    }

    public JsonObject toJSON() {
        JsonObject result = new JsonObject();

        result.put("id", id);
        if (owner == null)
            result.put("owner", null);
        else
            result.put("owner", owner.getId());

        JsonArray contactsIDs = new JsonArray();
        for (Person p : persons) {
            contactsIDs.add(p.getId());
        }
        result.put("persons", contactsIDs);

        return result;
    }

}

VertxServer

package fr.imta.addressbook.server;

import fr.imta.addressbook.model.Database;
import fr.imta.addressbook.server.handlers.AddressBookHandler;
import fr.imta.addressbook.server.handlers.PersonHandler;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.ext.web.handler.StaticHandler;

public class VertxServer {
    private Vertx vertx;
    private Database db;

    public VertxServer() {
        this.vertx = Vertx.vertx();
        
        this.db = new Database();
    }

    public void start() {
        Router router = Router.router(vertx);

        // add handlers for payload parsing and to allow swagger to send requests
        router.route().handler(BodyHandler.create());
        router.route().handler(CorsHandler.create().addOrigin("*").allowedMethod(HttpMethod.DELETE).allowedMethod(HttpMethod.PUT));

        // create handlers and registers routes
        PersonHandler ph = new PersonHandler(db);
        router.get("/api/person").handler(ph::getIds);
        router.post("/api/person").handler(ph::create);
        router.delete("/api/person/:id").handler(ph::delete);
        router.put("/api/person/:id").handler(ph::update);
        router.get("/api/person/:id").handler(ph::getById);

        // create handlers and registers routes
        AddressBookHandler ah = new AddressBookHandler(db);
        router.get("/api/addressbook").handler(ah::getIds);
        router.post("/api/addressbook").handler(ah::create);
        router.delete("/api/addressbook/:id").handler(ah::delete);
        router.put("/api/addressbook/:id").handler(ah::update);
        router.get("/api/addressbook/:id").handler(ah::getById);


        // serve the HTML frontend
        router.get("/").handler(StaticHandler.create("./static"));
        router.get("/static/*").handler(StaticHandler.create("./static"));

        // start the server and check for errors
        vertx.createHttpServer().requestHandler(router).listen(8080)
            .onSuccess(e -> 
                System.out.println("Server is listening on localhost:" + e.actualPort())
            ).onFailure(e -> {
                System.out.println("Cannot start server, got error: " + e.getLocalizedMessage());
                System.exit(1);
            });
    }

    public static void main(String[] args) {
        new VertxServer().start();
    }
}