TextApiResource.java
package info.textgrid.services.textapi;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import info.textgrid.namespaces.middleware.tgsearch.ResultType;
import info.textgrid.services.textapi.api.Actor;
import info.textgrid.services.textapi.api.Collection;
import info.textgrid.services.textapi.api.ContentItem;
import info.textgrid.services.textapi.api.Item;
import info.textgrid.services.textapi.api.Manifest;
import info.textgrid.services.textapi.api.Repository;
import info.textgrid.services.textapi.api.SequenceItem;
import info.textgrid.services.textapi.api.Title;
import info.textgrid.services.textapi.services.SearchClientService;
import io.quarkus.qute.Template;
import io.quarkus.qute.TemplateInstance;
import io.quarkus.runtime.LaunchMode;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
@Path("/textapi")
public class TextApiResource {
@Inject
SearchClientService searchClient;
@ConfigProperty(name = "textgrid.host")
String textgridHost;
@ConfigProperty(name = "service.url")
String serviceUrl;
@ConfigProperty(name = "validator.url")
String validatorUrl;
@ConfigProperty(name = "quarkus.application.version")
String version;
@Inject
LaunchMode launchMode;
@Inject
Template index;
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{id}/manifest.json")
@Operation(
summary = "Generate a TextAPI manifest",
description = "Use TextGridURI to list all items of an aggregation as TextAPI Items, "
+ "utilizing the aggregator for TEI->HTML transformation"
)
public Manifest manifest(
@Parameter(
description = "the TextGridURI to generate a manifest for",
example = "textgrid:wp1j.0"
)
@PathParam("id") String id) {
var meta = searchClient.infoQuery().getMetadata(id);
var label = meta.getResult().get(0).getObject().getGeneric().getProvided().getTitle().get(0);
var format = meta.getResult().get(0).getObject().getGeneric().getProvided().getFormat();
var r = new Repository().setId(id);
var m = new Manifest().setId(serviceUrl + "/" + id + "/manifest.json").setLabel(label).addRepository(r);
// every item of an for aggregations
if(format.equals("text/tg.aggregation+xml")) {
for (ResultType res: searchClient.navigationQuery().listAggregation(id).getResult()) {
var s = new SequenceItem()
.setId(serviceUrl + "/" + res.getTextgridUri() + "/item.json")
.setType("item")
.setLabel(res.getObject().getGeneric().getProvided().getTitle().get(0));
m.addSequenceItem(s);
}
} else {
var s = new SequenceItem().setId(serviceUrl + "/" + id + "/item.json").setLabel(label);
m.addSequenceItem(s);
}
return m;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{id}/item.json")
@Operation(
summary = "Generate a TextAPI item",
description = "Get aggregator URL for given TextGridUri for TEI -> HTML transformation"
)
public Item item(
@Parameter(
description= "textgridUri of a single item (normally listed inside a manifest)",
example = "textgrid:wmd3.0"
)
@PathParam("id") String id) {
var _id = serviceUrl + "/" + id + "/item.json";
var contentItem = new ContentItem().setUrl(textgridHost + "/1.0/aggregator/html/" + id + "?embedded=true");
// TODO: lang from textgrid metadata, what if not set? set to und (undetermined)
// https://de.wikipedia.org/wiki/ISO_639#Spezielle_Kennungen
var item = new Item().addContent(contentItem).setId(_id).addLang("und");
return item;
}
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/info")
@Operation(
summary = "Build info & config of this service"
)
public String info() {
return """
tg-textapi %s
textgrid host: %s
devmode: %s
""".formatted(version, textgridHost, launchMode.isDevOrTest());
}
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/")
@Operation(hidden = true) // hide operation from OpenAPI
public TemplateInstance index() {
return index.data("version", version)
.data("serviceUrl", serviceUrl)
.data("validatorUrl", validatorUrl)
.data("devmode", launchMode.isDevOrTest())
;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/search/collection.json")
public Collection search(@QueryParam("q") String query) {
return searchToCollection(query);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/search/{q}/collection.json")
public Collection searchPath(@PathParam("q") String query) {
return searchToCollection(query);
}
Collection searchToCollection(String query) {
var results = searchClient.searchQuery().setQuery(query).execute();
var description = "Search results for " + query;
var title = new Title().setTitle("Query: " + query);
var collector = new Actor().addRole("collector").setName("you via tgsearch").setId("yoursearch");
var collection = new Collection()
.setId("todo")
.setDescription(description)
.addTitle(title)
.addCollector(collector);
for (ResultType res: results.getResult()) {
var id = res.getObject().getGeneric().getGenerated().getTextgridUri().getValue();
var SequenceItem = new SequenceItem()
.setId(serviceUrl + "/" + id + "/manifest.json")
.setType("manifest")
.setLabel(res.getObject().getGeneric().getProvided().getTitle().get(0));
collection.addSequenceItem(SequenceItem);
}
return collection;
}
}