mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-11 14:50:56 +00:00
Merge branch 'master' into tracapi
This commit is contained in:
commit
7111ff7921
20 files changed
+523
-64
No files matched your search
Executable
+11
@@ -0,0 +1,11 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sse.common.Named;
|
||||
|
||||
public interface LeaderboardBase extends Named {
|
||||
/**
|
||||
* If a display name for the leaderboard has been defined,
|
||||
* this method returns it; otherwise, <code>null</code> is returned.
|
||||
*/
|
||||
String getDisplayName();
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sse.common.search.Hit;
|
||||
|
||||
/**
|
||||
* A generalization of <code>LeaderboardSearchResult</code> which has references to full-blown leaderboards, a regatta,
|
||||
* full leaderboard groups and the entire event; this form requires only the respective <code>...Base</code> flavors of
|
||||
* events, leaderboards and leaderboard groups which allows for the creation of a copy in a server that has been
|
||||
* receiving a search result from some other (remote) server, e.g., through JSON deserialization.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface LeaderboardSearchResultBase extends Hit {
|
||||
/**
|
||||
* The leaderboard that matches the search query.
|
||||
*/
|
||||
LeaderboardBase getLeaderboard();
|
||||
|
||||
String getRegattaName();
|
||||
|
||||
String getBoatClassName();
|
||||
|
||||
/**
|
||||
* If the leaderboard is part of one or more leaderboard groups, the leaderboard groups; an empty but
|
||||
* valid (non-<code>null</code>) collection otherwise.
|
||||
*/
|
||||
Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups();
|
||||
|
||||
/**
|
||||
* If there is a connection between an {@link EventBase} and the {@link #getLeaderboard() leaderboard}, e.g.,
|
||||
* because the {@link EventBase} has a {@link EventBase#getLeaderboardGroups() leaderboard group} that is part of
|
||||
* {@link #getLeaderboardGroups()} or the event has a course area attached to its {@link EventBase#getVenue() venue}
|
||||
* that is referenced by the leaderboard as its {@link Leaderboard#getDefaultCourseArea() default course area}, the
|
||||
* event is returned; <code>null</code> otherwise.
|
||||
*/
|
||||
EventBase getEvent();
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
|
||||
/**
|
||||
* This is what you get when you search a <code>RacingEventService</code> with its <code>search(...)</code> method. It
|
||||
* delivers the "real things," meaning that the leaderboards and events etc. are those objects currently living in the
|
||||
* server instance. This is richer than the de-serialized {@link LeaderboardSearchResultBase} objects you get when
|
||||
* fetching search results from remote instances, such as those described by a {@link RemoteSailingServerReference}.
|
||||
* However, for putting them into a DTO to transfer them to a web client, both are fine.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface LeaderboardSearchResult extends LeaderboardSearchResultBase {
|
||||
/**
|
||||
* The leaderboard that matches the search query.
|
||||
*/
|
||||
Leaderboard getLeaderboard();
|
||||
|
||||
/**
|
||||
* Returns the {@link RegattaLeaderboard#getRegatta() regatta leaderboard's regatta} if the
|
||||
* {@link #getLeaderboard() leaderboard} is a regatta leaderboard, or <code>null</code> otherwise.
|
||||
*/
|
||||
Regatta getRegatta();
|
||||
|
||||
/**
|
||||
* If the leaderboard is part of one or more leaderboard groups, the leaderboard groups; an empty but
|
||||
* valid (non-<code>null</code>) collection otherwise.
|
||||
*/
|
||||
Iterable<LeaderboardGroup> getLeaderboardGroups();
|
||||
|
||||
/**
|
||||
* If there is a connection between an {@link Event} and the {@link #getLeaderboard() leaderboard}, e.g., because
|
||||
* the {@link Event} has a {@link Event#getLeaderboardGroups() leaderboard group} that is part of {@link #getLeaderboardGroups()} or
|
||||
* the event has a course area attached to its {@link Event#getVenue() venue} that is referenced by the leaderboard as
|
||||
* its {@link Leaderboard#getDefaultCourseArea() default course area}, the event is returned; <code>null</code> otherwise.
|
||||
*/
|
||||
Event getEvent();
|
||||
}
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.LeaderboardBase;
|
||||
|
||||
public class LeaderboardBaseImpl implements LeaderboardBase {
|
||||
private static final long serialVersionUID = -5332972141344617372L;
|
||||
private final String name;
|
||||
private final String displayName;
|
||||
|
||||
public LeaderboardBaseImpl(String name, String displayName) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
|
||||
/**
|
||||
* The simplified version of a {@link LeaderboardSearchResult}, after JSON deserialization on a remote server. In particular,
|
||||
* the {@link Leaderboard} object is most certainly not available on the receiving end. {@link EventBase} and {@link LeaderboardGroupBase}
|
||||
* objects are
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class LeaderboardSearchResultBaseImpl implements LeaderboardSearchResultBase {
|
||||
private final LeaderboardBase leaderboard;
|
||||
private final String regattaName;
|
||||
private final Iterable<? extends LeaderboardGroupBase> leaderboardGroups;
|
||||
private final EventBase event;
|
||||
private final String boatClassName;
|
||||
|
||||
public LeaderboardSearchResultBaseImpl(LeaderboardBase leaderboard, String regattaName,
|
||||
String boatClassName, Iterable<? extends LeaderboardGroupBase> leaderboardGroups, EventBase event) {
|
||||
super();
|
||||
this.leaderboard = leaderboard;
|
||||
this.regattaName = regattaName;
|
||||
this.boatClassName = boatClassName;
|
||||
this.leaderboardGroups = leaderboardGroups;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardBase getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRegattaName() {
|
||||
return regattaName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBoatClassName() {
|
||||
return boatClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups() {
|
||||
return leaderboardGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventBase getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
|
||||
public class LeaderboardSearchResultImpl implements LeaderboardSearchResult {
|
||||
private final Leaderboard leaderboard;
|
||||
private final Event event;
|
||||
private final Set<LeaderboardGroup> leaderboardGroups;
|
||||
|
||||
public LeaderboardSearchResultImpl(Leaderboard leaderboard, Event event, Set<LeaderboardGroup> leaderboardGroups) {
|
||||
this.leaderboard = leaderboard;
|
||||
if (leaderboardGroups == null) {
|
||||
this.leaderboardGroups = Collections.emptySet();
|
||||
} else {
|
||||
this.leaderboardGroups = leaderboardGroups;
|
||||
}
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Regatta getRegatta() {
|
||||
final Regatta regatta;
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
regatta = ((RegattaLeaderboard) leaderboard).getRegatta();
|
||||
} else {
|
||||
regatta = null;
|
||||
}
|
||||
return regatta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRegattaName() {
|
||||
return getRegatta() != null ? getRegatta().getName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<LeaderboardGroup> getLeaderboardGroups() {
|
||||
return leaderboardGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBoatClassName() {
|
||||
BoatClass boatClass = getBoatClass();
|
||||
return boatClass == null ? null : boatClass.getName();
|
||||
}
|
||||
|
||||
public BoatClass getBoatClass() {
|
||||
final BoatClass boatClass;
|
||||
if (getRegatta() != null) {
|
||||
boatClass = getRegatta().getBoatClass();
|
||||
} else {
|
||||
boatClass = getBoatClassFromTrackedRaces();
|
||||
}
|
||||
return boatClass;
|
||||
}
|
||||
|
||||
private BoatClass getBoatClassFromTrackedRaces() {
|
||||
for (TrackedRace trackedRace : getLeaderboard().getTrackedRaces()) {
|
||||
return trackedRace.getRace().getBoatClass();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.LeaderboardBase;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
@@ -25,7 +26,6 @@ import com.sap.sailing.domain.leaderboard.caching.LiveLeaderboardUpdater;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@ import com.sap.sse.common.Util;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface Leaderboard extends Named {
|
||||
public interface Leaderboard extends LeaderboardBase {
|
||||
/**
|
||||
* If the leaderboard is a "matrix" with the cells being defined by a competitor / race "coordinate,"
|
||||
* then this interface defines the structure of the "cells."
|
||||
@@ -300,12 +300,6 @@ public interface Leaderboard extends Named {
|
||||
|
||||
void setDisplayName(Competitor competitor, String displayName);
|
||||
|
||||
/**
|
||||
* If a display name for the leaderboard has been defined,
|
||||
* this method returns it; otherwise, <code>null</code> is returned.
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
||||
void setDisplayName(String displayName);
|
||||
|
||||
/**
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.sap.sailing.server.gateway.deserialization.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
||||
import com.sap.sailing.domain.base.impl.LeaderboardBaseImpl;
|
||||
import com.sap.sailing.domain.base.impl.LeaderboardSearchResultBaseImpl;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardSearchResultJsonSerializer;
|
||||
|
||||
public class LeaderboardSearchResultBaseJsonDeserializer implements JsonDeserializer<LeaderboardSearchResultBase> {
|
||||
private final EventBaseJsonDeserializer eventDeserializer;
|
||||
|
||||
private final LeaderboardGroupBaseJsonDeserializer leaderboardGroupDeserializer;
|
||||
|
||||
public LeaderboardSearchResultBaseJsonDeserializer(EventBaseJsonDeserializer eventDeserializer,
|
||||
LeaderboardGroupBaseJsonDeserializer leaderboardGroupDeserializer) {
|
||||
super();
|
||||
this.eventDeserializer = eventDeserializer;
|
||||
this.leaderboardGroupDeserializer = leaderboardGroupDeserializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardSearchResultBase deserialize(JSONObject object) throws JsonDeserializationException {
|
||||
EventBase event = eventDeserializer.deserialize(Helpers.getNestedObjectSafe(object, LeaderboardSearchResultJsonSerializer.FIELD_EVENT));
|
||||
JSONObject leaderboardJson = Helpers.getNestedObjectSafe(object, LeaderboardSearchResultJsonSerializer.FIELD_LEADERBOARD);
|
||||
String leaderboardName = (String) leaderboardJson.get(LeaderboardSearchResultJsonSerializer.FIELD_LEADERBOARD_NAME);
|
||||
String leaderboardDisplayName = (String) leaderboardJson.get(LeaderboardSearchResultJsonSerializer.FIELD_LEADERBOARD_DISPLAY_NAME);
|
||||
String boatClassName = (String) leaderboardJson.get(LeaderboardSearchResultJsonSerializer.FIELD_LEADERBOARD_BOAT_CLASS_NAME);
|
||||
String regattaName = (String) leaderboardJson.get(LeaderboardSearchResultJsonSerializer.FIELD_LEADERBOARD_REGATTA_NAME);
|
||||
JSONArray leaderboardGroupsJson = Helpers.getNestedArraySafe(leaderboardJson, LeaderboardSearchResultJsonSerializer.FIELD_LEADERBOARD_IN_LEADERBOARD_GROUPS);
|
||||
List<LeaderboardGroupBase> leaderboardGroups = new ArrayList<LeaderboardGroupBase>();
|
||||
for (Object leaderboardGroupJson : leaderboardGroupsJson) {
|
||||
leaderboardGroups.add(leaderboardGroupDeserializer.deserialize((JSONObject) leaderboardGroupJson));
|
||||
}
|
||||
return new LeaderboardSearchResultBaseImpl(new LeaderboardBaseImpl(leaderboardName, leaderboardDisplayName),
|
||||
regattaName, boatClassName, leaderboardGroups, event);
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -21,10 +21,10 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
|
||||
public static final String FIELDS_LEADERBOARD_GROUPS = "leaderboardGroups";
|
||||
|
||||
private final JsonSerializer<Venue> venueSerializer;
|
||||
private final JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupSerializer;
|
||||
private final JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer;
|
||||
|
||||
public EventBaseJsonSerializer(JsonSerializer<Venue> venueSerializer, JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupSerializer) {
|
||||
this.leaderboardGroupSerializer = leaderboardGroupSerializer;
|
||||
public EventBaseJsonSerializer(JsonSerializer<Venue> venueSerializer, JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupBaseSerializer) {
|
||||
this.leaderboardGroupBaseSerializer = leaderboardGroupBaseSerializer;
|
||||
this.venueSerializer = venueSerializer;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
|
||||
JSONArray leaderboardGroups = new JSONArray();
|
||||
result.put(FIELDS_LEADERBOARD_GROUPS, leaderboardGroups);
|
||||
for (LeaderboardGroupBase lg : event.getLeaderboardGroups()) {
|
||||
leaderboardGroups.add(leaderboardGroupSerializer.serialize(lg));
|
||||
leaderboardGroups.add(leaderboardGroupBaseSerializer.serialize(lg));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.sap.sailing.server.gateway.serialization.impl;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
|
||||
public class LeaderboardSearchResultJsonSerializer implements JsonSerializer<LeaderboardSearchResult> {
|
||||
public static final String FIELD_SERVER_BASE_URL = "serverBaseURL";
|
||||
public static final String FIELD_EVENT = "event";
|
||||
public static final String FIELD_LEADERBOARD = "leaderboard";
|
||||
public static final String FIELD_LEADERBOARD_NAME = "name";
|
||||
public static final String FIELD_LEADERBOARD_DISPLAY_NAME = "displayName";
|
||||
public static final String FIELD_LEADERBOARD_BOAT_CLASS_NAME = "boatClassName";
|
||||
public static final String FIELD_LEADERBOARD_REGATTA_NAME = "regattaName";
|
||||
public static final String FIELD_LEADERBOARD_IN_LEADERBOARD_GROUPS = "inLeaderboardGroups";
|
||||
|
||||
private final JsonSerializer<EventBase> eventBaseJsonSerializer;
|
||||
private final JsonSerializer<LeaderboardGroupBase> leaderboardGroupBaseJsonSerializer;
|
||||
|
||||
public LeaderboardSearchResultJsonSerializer(JsonSerializer<EventBase> eventBaseJsonSerializer, JsonSerializer<LeaderboardGroupBase> leaderboardGroupBaseJsonSerializer) {
|
||||
this.eventBaseJsonSerializer = eventBaseJsonSerializer;
|
||||
this.leaderboardGroupBaseJsonSerializer = leaderboardGroupBaseJsonSerializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject serialize(LeaderboardSearchResult leaderboardSearchResult) {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put(
|
||||
FIELD_EVENT,
|
||||
leaderboardSearchResult.getEvent() == null ? null : eventBaseJsonSerializer
|
||||
.serialize(leaderboardSearchResult.getEvent()));
|
||||
JSONObject leaderboardJson = new JSONObject();
|
||||
result.put(FIELD_LEADERBOARD, leaderboardJson);
|
||||
Leaderboard leaderboard = leaderboardSearchResult.getLeaderboard();
|
||||
leaderboardJson.put(FIELD_LEADERBOARD_NAME, leaderboard.getName());
|
||||
leaderboardJson.put(FIELD_LEADERBOARD_DISPLAY_NAME, leaderboard.getDisplayName());
|
||||
final String boatClassName;
|
||||
final Regatta regatta;
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
regatta = ((RegattaLeaderboard) leaderboard).getRegatta();
|
||||
boatClassName = regatta.getBoatClass().getName();
|
||||
} else {
|
||||
regatta = null;
|
||||
boatClassName = leaderboardSearchResult.getBoatClassName();
|
||||
}
|
||||
leaderboardJson.put(FIELD_LEADERBOARD_BOAT_CLASS_NAME, boatClassName);
|
||||
leaderboardJson.put(FIELD_LEADERBOARD_REGATTA_NAME, regatta == null ? null : regatta.getName());
|
||||
JSONArray leaderboardGroupsJson = new JSONArray();
|
||||
leaderboardJson.put(FIELD_LEADERBOARD_IN_LEADERBOARD_GROUPS, leaderboardGroupsJson);
|
||||
for (LeaderboardGroup lg : leaderboardSearchResult.getLeaderboardGroups()) {
|
||||
leaderboardGroupsJson.add(leaderboardGroupBaseJsonSerializer.serialize(lg));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -13,8 +13,7 @@ public class RestApiApplication extends Application {
|
||||
classes.add(EventsResource.class);
|
||||
classes.add(RegattasResource.class);
|
||||
classes.add(LeaderboardsResource.class);
|
||||
// classes.add(WindResource.class);
|
||||
|
||||
classes.add(SearchResource.class);
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/SearchResource.java
Executable
+48
@@ -0,0 +1,48 @@
|
||||
package com.sap.sailing.server.gateway.jaxrs.api;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardSearchResultJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
|
||||
import com.sap.sse.common.search.KeywordQuery;
|
||||
import com.sap.sse.common.search.Result;
|
||||
|
||||
@Path("/v1/search")
|
||||
public class SearchResource extends AbstractSailingServerResource {
|
||||
private final JsonSerializer<LeaderboardSearchResult> serializer;
|
||||
|
||||
public SearchResource() {
|
||||
final LeaderboardGroupBaseJsonSerializer leaderboardGroupSerializer = new LeaderboardGroupBaseJsonSerializer();
|
||||
serializer = new LeaderboardSearchResultJsonSerializer(new EventBaseJsonSerializer(new VenueJsonSerializer(
|
||||
new CourseAreaJsonSerializer()), leaderboardGroupSerializer), leaderboardGroupSerializer);
|
||||
}
|
||||
|
||||
private Result<LeaderboardSearchResult> search(KeywordQuery query) {
|
||||
return getService().search(query);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces("application/json;charset=UTF-8")
|
||||
public Response search(@QueryParam("q") String keywords) {
|
||||
KeywordQuery query = new KeywordQuery(keywords.split(" "));
|
||||
Iterable<LeaderboardSearchResult> searchResults = search(query).getHits();
|
||||
JSONArray jsonSearchResults = new JSONArray();
|
||||
for (LeaderboardSearchResult searchResult : searchResults) {
|
||||
jsonSearchResults.add(serializer.serialize(searchResult));
|
||||
}
|
||||
return Response.ok(jsonSearchResults.toJSONString(), MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
}
|
||||
+60
-5
@@ -3,6 +3,7 @@ package com.sap.sailing.server.test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
@@ -21,7 +22,11 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResultBase;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
@@ -36,14 +41,25 @@ import com.sap.sailing.domain.common.dto.RegattaCreationParametersDTO;
|
||||
import com.sap.sailing.domain.common.dto.SeriesCreationParametersDTO;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
||||
import com.sap.sailing.domain.test.AbstractTracTracLiveTest;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
import com.sap.sailing.server.LeaderboardSearchResult;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardSearchResultBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardSearchResultJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
|
||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
import com.sap.sailing.server.operationaltransformation.AddColumnToSeries;
|
||||
import com.sap.sailing.server.operationaltransformation.AddRaceDefinition;
|
||||
@@ -241,10 +257,14 @@ public class SearchServiceTest {
|
||||
Result<LeaderboardSearchResult> searchResults = server.search(new KeywordQuery(Arrays.asList(new String[] { "Kiel" })));
|
||||
assertEquals(2, Util.size(searchResults.getHits()));
|
||||
final Iterator<LeaderboardSearchResult> iterator = searchResults.getHits().iterator();
|
||||
Regatta firstFoundRegatta = iterator.next().getRegatta();
|
||||
final LeaderboardSearchResult firstMatch = iterator.next();
|
||||
Regatta firstFoundRegatta = firstMatch.getRegatta();
|
||||
assertSame(pfingstbusch29er, firstFoundRegatta);
|
||||
Regatta secondFoundRegatta = iterator.next().getRegatta();
|
||||
assertSame(pfingstbusch, firstMatch.getEvent());
|
||||
final LeaderboardSearchResult secondMatch = iterator.next();
|
||||
Regatta secondFoundRegatta = secondMatch.getRegatta();
|
||||
assertSame(pfingstbusch470, secondFoundRegatta);
|
||||
assertSame(pfingstbusch, secondMatch.getEvent());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -252,9 +272,44 @@ public class SearchServiceTest {
|
||||
Result<LeaderboardSearchResult> searchResults = server.search(new KeywordQuery(Arrays.asList(new String[] { "Buhl" })));
|
||||
assertEquals(2, Util.size(searchResults.getHits()));
|
||||
final Iterator<LeaderboardSearchResult> iter = searchResults.getHits().iterator();
|
||||
Regatta earlierStartRegatta = iter.next().getRegatta();
|
||||
final LeaderboardSearchResult firstMatch = iter.next();
|
||||
Regatta earlierStartRegatta = firstMatch.getRegatta();
|
||||
assertSame(pfingstbusch470, earlierStartRegatta);
|
||||
Regatta laterStartRegatta = iter.next().getRegatta();
|
||||
assertSame(pfingstbusch, firstMatch.getEvent());
|
||||
final LeaderboardSearchResult secondMatch = iter.next();
|
||||
Regatta laterStartRegatta = secondMatch.getRegatta();
|
||||
assertSame(aalRegatta, laterStartRegatta);
|
||||
assertSame(aalEvent, secondMatch.getEvent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializeAndDeserializeSearchResult() throws JsonDeserializationException {
|
||||
Result<LeaderboardSearchResult> searchResults = server.search(new KeywordQuery(Arrays.asList(new String[] { "Buhl" })));
|
||||
LeaderboardGroupBaseJsonSerializer leaderboardGroupBaseJsonSerializer = new LeaderboardGroupBaseJsonSerializer();
|
||||
LeaderboardSearchResultJsonSerializer serializer = new LeaderboardSearchResultJsonSerializer(new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()),
|
||||
leaderboardGroupBaseJsonSerializer),
|
||||
leaderboardGroupBaseJsonSerializer);
|
||||
LeaderboardGroupBaseJsonDeserializer leaderboardGroupBaseJsonDeserializer = new LeaderboardGroupBaseJsonDeserializer();
|
||||
LeaderboardSearchResultBaseJsonDeserializer deserializer = new LeaderboardSearchResultBaseJsonDeserializer(
|
||||
new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)),
|
||||
leaderboardGroupBaseJsonDeserializer), leaderboardGroupBaseJsonDeserializer);
|
||||
final LeaderboardSearchResult expected = searchResults.getHits().iterator().next();
|
||||
LeaderboardSearchResultBase deserialized = deserializer.deserialize(serializer.serialize(expected));
|
||||
assertEquals("Pfingstbusch (470)", deserialized.getRegattaName());
|
||||
assertEquals(expected.getEvent().getName(), deserialized.getEvent().getName());
|
||||
assertEquals(expected.getEvent().getId(), deserialized.getEvent().getId());
|
||||
assertEquals(expected.getEvent().getStartDate(), deserialized.getEvent().getStartDate());
|
||||
assertEquals(expected.getEvent().getEndDate(), deserialized.getEvent().getEndDate());
|
||||
assertEquals(expected.getEvent().getVenue().getName(), deserialized.getEvent().getVenue().getName());
|
||||
Iterator<LeaderboardGroup> expectedLGs = expected.getLeaderboardGroups().iterator();
|
||||
Iterator<? extends LeaderboardGroupBase> deserializedLGs = deserialized.getLeaderboardGroups().iterator();
|
||||
while (expectedLGs.hasNext()) {
|
||||
assertTrue(deserializedLGs.hasNext());
|
||||
LeaderboardGroup expectedLG = expectedLGs.next();
|
||||
LeaderboardGroupBase deserializedLG = deserializedLGs.next();
|
||||
assertEquals(expectedLG.getId(), deserializedLG.getId());
|
||||
assertEquals(expectedLG.getName(), deserializedLG.getName());
|
||||
assertEquals(expectedLG.getDescription(), deserializedLG.getDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.sap.sailing.server;
|
||||
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sse.common.search.Hit;
|
||||
|
||||
public interface LeaderboardSearchResult extends Hit {
|
||||
Regatta getRegatta();
|
||||
Leaderboard getLeaderboard();
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
package com.sap.sailing.server.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.server.LeaderboardSearchResult;
|
||||
|
||||
public class LeaderboardSearchResultImpl implements LeaderboardSearchResult {
|
||||
private final Leaderboard leaderboard;
|
||||
|
||||
public LeaderboardSearchResultImpl(Leaderboard leaderboard) {
|
||||
this.leaderboard = leaderboard;
|
||||
}
|
||||
|
||||
public Regatta getRegatta() {
|
||||
final Regatta regatta;
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
regatta = ((RegattaLeaderboard) leaderboard).getRegatta();
|
||||
} else {
|
||||
regatta = null;
|
||||
}
|
||||
return regatta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -39,6 +39,7 @@ import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnInSeries;
|
||||
@@ -133,7 +134,6 @@ import com.sap.sailing.operationaltransformation.Operation;
|
||||
import com.sap.sailing.server.OperationExecutionListener;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
import com.sap.sailing.server.LeaderboardSearchResult;
|
||||
import com.sap.sailing.server.Replicator;
|
||||
import com.sap.sailing.server.masterdata.DataImportLockWithProgress;
|
||||
import com.sap.sailing.server.operationaltransformation.AddCourseArea;
|
||||
|
||||
+16
-2
@@ -1,15 +1,19 @@
|
||||
package com.sap.sailing.server.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.impl.LeaderboardSearchResultImpl;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.server.LeaderboardSearchResult;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.filter.AbstractListFilter;
|
||||
@@ -30,9 +34,12 @@ import com.sap.sse.common.search.ResultImpl;
|
||||
public class RegattaByKeywordSearchService {
|
||||
Result<LeaderboardSearchResult> search(final RacingEventService racingEventService, KeywordQuery query) {
|
||||
ResultImpl<LeaderboardSearchResult> result = new ResultImpl<>(query, new RegattaSearchResultRanker(racingEventService));
|
||||
final Map<Leaderboard, Event> eventForLeaderboard = new HashMap<>();
|
||||
final Map<Leaderboard, Set<LeaderboardGroup>> leaderboardGroupsForLeaderboard = new HashMap<>();
|
||||
AbstractListFilter<Leaderboard> leaderboardFilter = new AbstractListFilter<Leaderboard>() {
|
||||
@Override
|
||||
public Iterable<String> getStrings(Leaderboard leaderboard) {
|
||||
// TODO allow recording which part of the leaderboard was matched by the keywords by returning "annotated strings" that the matcher can understand
|
||||
List<String> leaderboardStrings = new ArrayList<>();
|
||||
leaderboardStrings.add(leaderboard.getName());
|
||||
leaderboardStrings.add(leaderboard.getDisplayName());
|
||||
@@ -49,16 +56,23 @@ public class RegattaByKeywordSearchService {
|
||||
for (LeaderboardGroup leaderboardGroup : leaderboardGroupsHostingLeaderboard) {
|
||||
leaderboardStrings.add(leaderboardGroup.getName());
|
||||
leaderboardStrings.add(leaderboardGroup.getDescription());
|
||||
Set<LeaderboardGroup> leaderboardGroups = leaderboardGroupsForLeaderboard.get(leaderboard);
|
||||
if (leaderboardGroups == null) {
|
||||
leaderboardGroups = new HashSet<>();
|
||||
leaderboardGroupsForLeaderboard.put(leaderboard, leaderboardGroups);
|
||||
}
|
||||
leaderboardGroups.add(leaderboardGroup);
|
||||
}
|
||||
for (Event event : getEventsHostingLeaderboard(leaderboard, racingEventService, leaderboardGroupsHostingLeaderboard)) {
|
||||
leaderboardStrings.add(event.getName());
|
||||
leaderboardStrings.add(event.getVenue().getName());
|
||||
eventForLeaderboard.put(leaderboard, event);
|
||||
}
|
||||
return leaderboardStrings;
|
||||
}
|
||||
};
|
||||
for (Leaderboard matchingLeaderboard : leaderboardFilter.applyFilter(query.getKeywords(), racingEventService.getLeaderboards().values())) {
|
||||
result.addHit(new LeaderboardSearchResultImpl(matchingLeaderboard));
|
||||
result.addHit(new LeaderboardSearchResultImpl(matchingLeaderboard, eventForLeaderboard.get(matchingLeaderboard), leaderboardGroupsForLeaderboard.get(matchingLeaderboard)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,13 +5,13 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.base.LeaderboardSearchResult;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.LeaderboardSearchResult;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class RegattaSearchResultRanker implements Comparator<LeaderboardSearchResult> {
|
||||
|
||||
@@ -1,20 +1,37 @@
|
||||
package com.sap.sse.common.search;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class KeywordQuery implements Query {
|
||||
private final Iterable<String> keywords;
|
||||
|
||||
public KeywordQuery(String... keywords) {
|
||||
this.keywords = Arrays.asList(keywords);
|
||||
this.keywords = trim(Arrays.asList(keywords));
|
||||
}
|
||||
|
||||
private Iterable<String> trim(Iterable<String> keywords) {
|
||||
final List<String> result = new ArrayList<String>(Util.size(keywords));
|
||||
for (String keyword : keywords) {
|
||||
result.add(keyword.trim());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public KeywordQuery(Iterable<String> keywords) {
|
||||
super();
|
||||
this.keywords = keywords;
|
||||
this.keywords = trim(keywords);
|
||||
}
|
||||
|
||||
public Iterable<String> getKeywords() {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ""+keywords;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user