improved Controller and Rest Front-end structure

This commit is contained in:
s5260822 2025-03-18 16:40:42 +01:00
parent 05154c5259
commit fa5d5e151d
5 changed files with 306 additions and 69 deletions

View file

@ -764,6 +764,14 @@ public class MongoDBHandler {
}
}
public String getMemberPhoto(String memberId) {
Document photoDocument = memberPhotoCollection.find(eq("memberId", memberId)).first();
if (photoDocument == null) {
return null;
}
return photoDocument.getString("base64");
}
public void close() {
mongoClient.close();
}

View file

@ -65,6 +65,11 @@ public class MongoPprUtils {
return agendaItemsCollection;
}
public static MongoCollection<Document> getPicturesCollection() {
if (picturesCollection == null) picturesCollection = MongoDBHandler.getMongoDatabase().getCollection(PICTURES_COLLECTION_NAME);
return picturesCollection;
}
/**
* Create the Speaker Collection and useful indices for it
*/
@ -400,4 +405,14 @@ public class MongoPprUtils {
return new HtmlSpeech(speechDoc);
}
public static String getMemberPhoto(String memberId) {
Document filter = new Document("memberId", memberId);
Document pictureDoc = getPicturesCollection().find(filter).first();
if (pictureDoc == null) {
return null;
} else {
return (String) pictureDoc.get("base64");
}
}
}

View file

@ -0,0 +1,147 @@
package org.texttechnologylab.project.gruppe_05_1.rest;
import gnu.trove.impl.sync.TSynchronizedShortObjectMap;
import io.javalin.http.Context;
import io.javalin.openapi.*;
import org.apache.commons.collections.bag.SynchronizedSortedBag;
import org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils;
import org.texttechnologylab.project.gruppe_05_1.domain.html.HtmlSpeech;
import org.texttechnologylab.project.gruppe_05_1.domain.html.Parlamentarier;
import org.texttechnologylab.project.gruppe_05_1.domain.html.ParlamentarierDetails;
import org.texttechnologylab.project.gruppe_05_1.domain.speech.SpeechMetaData;
import org.texttechnologylab.project.gruppe_05_1.util.Logger;
import org.texttechnologylab.project.gruppe_05_1.util.PPRUtils;
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Speech;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FrontEndController {
@OpenApi(
summary = "Get alle Parlamentarier. Man kann nach Vor-, Nachname oder Partei filtern.",
description = "Listet alle Parlamentarier bzw. diejenige, welche den Filter entsprechen",
operationId = "getAllParlamentarier",
path = "/",
methods = HttpMethod.GET,
tags = {"Parlamentarier"},
queryParams = {
@OpenApiParam(name = "filter", description = "Full-Text-Filter. Kann Vorname, Nachname oder Partei filtern", required = false),
},
responses = {
@OpenApiResponse(status = "200", content = {@OpenApiContent(from = Parlamentarier[].class)})
})
public static void getAllParlamentarier(Context ctx) {
String filter = ctx.queryParam("filter");
Logger.info("Filter: '" + filter + "'");
List<Parlamentarier> parlamentarier = MongoPprUtils.getAllParlamentarier(filter);
PPRUtils.sortParlamentarierByName(parlamentarier);
Logger.info(parlamentarier.size() + " MdBs gefunden");
Map<String, Object> attributes = new HashMap<>();
attributes.put("parlamentarier", parlamentarier);
attributes.put("filter", filter);
ctx.render("parlamentarier.ftl", attributes);
}
/**
* Zeigt die Details eines Parlamentariers an:
* - persönliche Daten (Geburtsdatum, -ort, Vita, Religion etc.).
* - Mitgliederschaften, falls vorhanden
* - Fotos, falls vorhanden
* @param ctx JavaLin-Context
*/
@OpenApi(
summary = "Zeigt die Details eines Parlamentariers an",
description = "Zeigt persönliche Daten, Mitgliederschaften, Fotos",
operationId = "getParlamentarierDetails",
path = "/portfolio/{id}",
methods = HttpMethod.GET,
tags = {"Parlamentarier"},
pathParams = {
@OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
},
responses = {
@OpenApiResponse(status = "200", content = {@OpenApiContent(from = ParlamentarierDetails.class)})
})
public static void getParlamentarierDetails(Context ctx) {
String id = ctx.pathParam("id");
Logger.info("getParlamentarierDetails, ID = " + id);
ParlamentarierDetails pd = MongoPprUtils.getParlamentarierDetailsByID(id);
Map<String, Object> attributes = new HashMap<>();
attributes.put("p", pd);
Long speechCount = MongoPprUtils.countSpeechesOfSpeaker(pd.getId());
attributes.put("speechesCount", speechCount);
attributes.put("pic", MongoPprUtils.getMemberPhoto(pd.getId()));
if (speechCount == 0) {
attributes.put("speechesPlaceholder", null);
} else {
attributes.put("speechesPlaceholder", new ArrayList<>());
}
ctx.render("parlamentarierDetails.ftl", attributes);
}
/**
* Liste alle Reden eines Parlamentariers an
* @param ctx Javalin Context
*/
@OpenApi(
summary = "Liste alle Reden eines Parlamentariers an",
description = "Liste alle Reden eines Parlamentariers an",
operationId = "listSpeeches",
path = "/reden/{id}",
methods = HttpMethod.GET,
tags = {"Rede"},
pathParams = {
@OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
},
responses = {
@OpenApiResponse(status = "200", content = {@OpenApiContent(from = Speech[].class)})
})
public static void listSpeeches(Context ctx) {
String parlamentarierId = ctx.pathParam("id");
ParlamentarierDetails p = MongoPprUtils.getParlamentarierDetailsByID(parlamentarierId);
List<SpeechMetaData> speechMetaDataList = MongoPprUtils.getSpeechesMetadataForSpeaker(parlamentarierId);
Map<String, Object> attributes = new HashMap<>();
attributes.put("p", p);
attributes.put("speechesMetaDataList", speechMetaDataList);
ctx.render("showSpeechesList.ftl", attributes);
}
/**
* Zeige eine bestimmte Rede des Parlamentariers an
* @param ctx Javalin Context
*/
@OpenApi(
summary = "Zeige eine bestimmte Rede des Parlamentariers an",
description = "Zeige eine bestimmte Rede des Parlamentariers an",
operationId = "showSpeech",
path = "/reden/{id}/{redeID}",
methods = HttpMethod.GET,
tags = {"Rede"},
pathParams = {
@OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
@OpenApiParam(name = "redeId", description = "id der Rede", required = true),
},
responses = {
@OpenApiResponse(status = "200", content = {@OpenApiContent(from = Speech.class)})
})
public static void showSpeech(Context ctx) {
String redeId = ctx.pathParam("redeId");
Map<String, Object> attributes = new HashMap<>();
HtmlSpeech speech = MongoPprUtils.getSpeechByKey(redeId);
attributes.put("s", speech);
ctx.render("speech.ftl", attributes);
}
}

View file

@ -1,69 +1,67 @@
package org.texttechnologylab.project.gruppe_05_1.rest;
import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import io.javalin.Javalin;
import io.javalin.http.staticfiles.Location;
import io.javalin.openapi.plugin.OpenApiPlugin;
import io.javalin.openapi.plugin.redoc.ReDocPlugin;
import io.javalin.rendering.template.JavalinFreemarker;
import org.texttechnologylab.project.gruppe_05_1.util.Logger;
import java.io.File;
import java.io.IOException;
import static org.texttechnologylab.project.gruppe_05_1.Main.JAVALIN_STATIC_FILES_DIR;
import static org.texttechnologylab.project.gruppe_05_1.Main.JAVALIN_TEMPLATE_DIR;
public class RESTHandler {
public void startJavalin() {
// Javalin Konfiguration (z.B. port)
JavalinConfig jlConfig = new JavalinConfig();
int port = jlConfig.getPort();
// FreeMarker Konfiguration
Configuration fmConfig = new Configuration(Configuration.VERSION_2_3_33);
fmConfig.setDefaultEncoding("UTF-8");
try {
fmConfig.setDirectoryForTemplateLoading(new File(JAVALIN_TEMPLATE_DIR));
} catch (IOException e) {
throw new RuntimeException(e);
}
fmConfig.setLogTemplateExceptions(true);
fmConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// Erzeuge die Javalin app
Javalin app = Javalin.create(config -> {
config.staticFiles.add(JAVALIN_STATIC_FILES_DIR, Location.EXTERNAL); // momentan nicht benutzt
config.fileRenderer(new JavalinFreemarker(fmConfig));
config.registerPlugin(new OpenApiPlugin(pluginConfig -> {
// Define OpenAPI spec configuration
pluginConfig.withDefinitionConfiguration((version, definition) -> {
definition.withOpenApiInfo(info -> info.setTitle("Javalin OpenAPI Documentation"));
});
}));
config.registerPlugin(new ReDocPlugin());
})
.start(port);
Logger.info("Javalin app started on http://localhost:" + port);
// Routes
// ======
// Parlamentarier
app.get("/", ParlamentarierController::getAllParlamentarier);
app.get("/portfolio/{id}", ParlamentarierController::getParlamentarierDetails);
app.delete("/deleteParlamentarier", ParlamentarierController::deleteAllParlamentarier);
// Reden
app.get("/reden/{id}", SpeechController::listSpeeches); // zeige Reden eines Parlamentariers an
app.get("/reden/{id}/{redeId}", SpeechController::showSpeech); // zeige eine bestimmte Rede des Parlamentariers an
}
}
package org.texttechnologylab.project.gruppe_05_1.rest;
import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import io.javalin.Javalin;
import io.javalin.http.staticfiles.Location;
import io.javalin.openapi.plugin.OpenApiPlugin;
import io.javalin.openapi.plugin.redoc.ReDocPlugin;
import io.javalin.rendering.template.JavalinFreemarker;
import org.texttechnologylab.project.gruppe_05_1.util.Logger;
import java.io.File;
import java.io.IOException;
import static org.texttechnologylab.project.gruppe_05_1.Main.JAVALIN_STATIC_FILES_DIR;
import static org.texttechnologylab.project.gruppe_05_1.Main.JAVALIN_TEMPLATE_DIR;
public class RESTHandler {
public void startJavalin() {
// Javalin Konfiguration (z.B. port)
JavalinConfig jlConfig = new JavalinConfig();
int port = jlConfig.getPort();
// FreeMarker Konfiguration
Configuration fmConfig = new Configuration(Configuration.VERSION_2_3_33);
fmConfig.setDefaultEncoding("UTF-8");
try {
fmConfig.setDirectoryForTemplateLoading(new File(JAVALIN_TEMPLATE_DIR));
} catch (IOException e) {
throw new RuntimeException(e);
}
fmConfig.setLogTemplateExceptions(true);
fmConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// Erzeuge die Javalin app
Javalin app = Javalin.create(config -> {
config.staticFiles.add(JAVALIN_STATIC_FILES_DIR, Location.EXTERNAL); // momentan nicht benutzt
config.fileRenderer(new JavalinFreemarker(fmConfig));
config.registerPlugin(new OpenApiPlugin(pluginConfig -> {
// Define OpenAPI spec configuration
pluginConfig.withDefinitionConfiguration((version, definition) -> {
definition.withOpenApiInfo(info -> info.setTitle("Javalin OpenAPI Documentation"));
});
}));
config.registerPlugin(new ReDocPlugin());
})
.start(port);
Logger.info("Javalin app started on http://localhost:" + port);
// Routes
// ======
// Parlamentarier
app.get("/", FrontEndController::getAllParlamentarier);
app.get("/portfolio/{id}", FrontEndController::getParlamentarierDetails);
app.delete("/deleteParlamentarier", ParlamentarierController::deleteAllParlamentarier);
// Reden
app.get("/reden/{id}", FrontEndController::listSpeeches); // zeige Reden eines Parlamentariers an
app.get("/reden/{id}/{redeId}", FrontEndController::showSpeech); // zeige eine bestimmte Rede des Parlamentariers an
}
}

View file

@ -0,0 +1,69 @@
package org.texttechnologylab.project.gruppe_05_1.rest;
import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import io.javalin.Javalin;
import io.javalin.http.staticfiles.Location;
import io.javalin.openapi.plugin.OpenApiPlugin;
import io.javalin.openapi.plugin.redoc.ReDocPlugin;
import io.javalin.rendering.template.JavalinFreemarker;
import org.texttechnologylab.project.gruppe_05_1.util.Logger;
import java.io.File;
import java.io.IOException;
import static org.texttechnologylab.project.gruppe_05_1.Main.JAVALIN_STATIC_FILES_DIR;
import static org.texttechnologylab.project.gruppe_05_1.Main.JAVALIN_TEMPLATE_DIR;
public class RESTHandlerOld {
public void startJavalin() {
// Javalin Konfiguration (z.B. port)
JavalinConfig jlConfig = new JavalinConfig();
int port = jlConfig.getPort();
// FreeMarker Konfiguration
Configuration fmConfig = new Configuration(Configuration.VERSION_2_3_33);
fmConfig.setDefaultEncoding("UTF-8");
try {
fmConfig.setDirectoryForTemplateLoading(new File(JAVALIN_TEMPLATE_DIR));
} catch (IOException e) {
throw new RuntimeException(e);
}
fmConfig.setLogTemplateExceptions(true);
fmConfig.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// Erzeuge die Javalin app
Javalin app = Javalin.create(config -> {
config.staticFiles.add(JAVALIN_STATIC_FILES_DIR, Location.EXTERNAL); // momentan nicht benutzt
config.fileRenderer(new JavalinFreemarker(fmConfig));
config.registerPlugin(new OpenApiPlugin(pluginConfig -> {
// Define OpenAPI spec configuration
pluginConfig.withDefinitionConfiguration((version, definition) -> {
definition.withOpenApiInfo(info -> info.setTitle("Javalin OpenAPI Documentation"));
});
}));
config.registerPlugin(new ReDocPlugin());
})
.start(port);
Logger.info("Javalin app started on http://localhost:" + port);
// Routes
// ======
// Parlamentarier
app.get("/", ParlamentarierController::getAllParlamentarier);
app.get("/portfolio/{id}", ParlamentarierController::getParlamentarierDetails);
app.delete("/deleteParlamentarier", ParlamentarierController::deleteAllParlamentarier);
// Reden
app.get("/reden/{id}", SpeechController::listSpeeches); // zeige Reden eines Parlamentariers an
app.get("/reden/{id}/{redeId}", SpeechController::showSpeech); // zeige eine bestimmte Rede des Parlamentariers an
}
}