mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-19 10:39:59 +00:00
Renamed project to xmlexport as this matches the purpose better
This commit is contained in:
1 parent
16103ce777
commit
6d56eeb43d
14 files changed
+9
-9
No files matched your search
Executable
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="lib" path="lib/jdom.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1 @@
|
||||
bin
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.sap.sailing.xmlexport</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,8 @@
|
||||
#Thu Jan 19 09:59:32 CET 2012
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
@@ -0,0 +1,4 @@
|
||||
#Wed Oct 05 23:23:07 CEST 2011
|
||||
eclipse.preferences.version=1
|
||||
pluginProject.extensions=false
|
||||
resolve.requirebundle=false
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Leaderboard XML Export
|
||||
Bundle-SymbolicName: com.sap.sailing.xmlexport
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Import-Package: javax.servlet;version="2.6.0",
|
||||
javax.servlet.http;version="2.6.0",
|
||||
org.osgi.framework;version="1.6.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: com.sap.sailing.server,
|
||||
com.sap.sailing.server.gateway,
|
||||
com.sap.sailing.domain,
|
||||
com.sap.sailing.domain.tractracadapter,
|
||||
com.sap.sailing.domain.common
|
||||
Bundle-ClassPath: lib/jdom.jar,
|
||||
.
|
||||
Web-ContextPath: /export
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
|
||||
<servlet>
|
||||
<servlet-name>XmlExportServlet</servlet-name>
|
||||
<servlet-class>com.sap.sailing.xmlexport.XmlExportServlet</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>XmlExportServlet</servlet-name>
|
||||
<url-pattern>/xml</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
lib/jdom.jar,\
|
||||
WEB-INF/
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>root</artifactId>
|
||||
<groupId>com.sap.sailing</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>com.sap.sailing.xmlexport</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
@@ -0,0 +1,312 @@
|
||||
package com.sap.sailing.xmlexport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.jdom.Element;
|
||||
import org.jdom.output.Format;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.Nationality;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public abstract class ExportAction {
|
||||
private HttpServletRequest req;
|
||||
private HttpServletResponse res;
|
||||
|
||||
private RacingEventService service;
|
||||
|
||||
public ExportAction(HttpServletRequest req, HttpServletResponse res, RacingEventService service) {
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public String getAttribute(String name) {
|
||||
return this.req.getParameter(name);
|
||||
}
|
||||
|
||||
public RacingEventService getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public Leaderboard getLeaderboard() throws IOException, ServletException {
|
||||
final String leaderboardName = getAttribute("name");
|
||||
if (leaderboardName == null) {
|
||||
throw new ServletException("Use the name= parameter to specify the leaderboard");
|
||||
}
|
||||
final Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard == null) {
|
||||
throw new ServletException("Leaderboard " + leaderboardName + " not found.");
|
||||
}
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
protected String cleanRaceName(String raceName) {
|
||||
String newRaceName = raceName;
|
||||
if (raceName.matches("[A-Za-z ]*\\d")) {
|
||||
Pattern regex = Pattern.compile("([A-Za-z ]*)(\\d)");
|
||||
Matcher matcher = regex.matcher(raceName);
|
||||
String raceNameFirstPart = matcher.replaceAll("$1");
|
||||
String raceNumber = matcher.replaceAll("$2");
|
||||
try {
|
||||
if (Integer.parseInt(raceNumber) < 10) {
|
||||
raceNumber = "0" + raceNumber;
|
||||
newRaceName = raceNameFirstPart + raceNumber;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return newRaceName;
|
||||
}
|
||||
|
||||
public Long getTotalTimeSailedInMilliseconds(final Competitor competitor, final TimePoint timePoint, boolean alsoReturnTimeIfCompetitorHasNotFinishedRace) throws IOException, ServletException {
|
||||
Long result = null;
|
||||
for (TrackedRace trackedRace : getLeaderboard().getTrackedRaces()) {
|
||||
if (Util.contains(trackedRace.getRace().getCompetitors(), competitor)) {
|
||||
NavigableSet<MarkPassing> markPassings = trackedRace.getMarkPassings(competitor);
|
||||
if (!markPassings.isEmpty()) {
|
||||
TimePoint from = trackedRace.getStartOfRace(); // start counting at race start, not when the competitor passed the line
|
||||
if (from != null && !timePoint.before(from)) { // but only if the race started after timePoint
|
||||
TimePoint to;
|
||||
if (timePoint.after(markPassings.last().getTimePoint())
|
||||
&& markPassings.last().getWaypoint() == trackedRace.getRace().getCourse()
|
||||
.getLastWaypoint()) {
|
||||
// stop counting when competitor finished the race
|
||||
to = markPassings.last().getTimePoint();
|
||||
} else {
|
||||
// in contrary to AbstractSimpleLeaderboardImpl#getTotalTimeSailedInMilliseconds
|
||||
// this method will not return null if a competitor did not finish the race but
|
||||
// will return all data until here
|
||||
if (!alsoReturnTimeIfCompetitorHasNotFinishedRace) {
|
||||
if (trackedRace.getEndOfTracking() != null
|
||||
&& timePoint.after(trackedRace.getEndOfTracking())) {
|
||||
result = null; // race not finished until end of tracking; no reasonable value can be
|
||||
// computed for competitor
|
||||
break;
|
||||
} else {
|
||||
to = timePoint;
|
||||
}
|
||||
} else {
|
||||
// count until last mark passing - we can not find
|
||||
// any time point later than that because the competitor
|
||||
// could have sailed away from the race course
|
||||
to = markPassings.last().getTimePoint();
|
||||
}
|
||||
}
|
||||
long timeSpent = to.asMillis() - from.asMillis();
|
||||
if (result == null) {
|
||||
result = timeSpent;
|
||||
} else {
|
||||
result += timeSpent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Distance getDistanceTraveled(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint, boolean alsoReturnDistanceIfCompetitorHasNotFinishedRace) {
|
||||
NavigableSet<MarkPassing> markPassings = trackedRace.getMarkPassings(competitor);
|
||||
if (markPassings.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
TimePoint end = timePoint;
|
||||
if (markPassings.last().getWaypoint() == trackedRace.getRace().getCourse().getLastWaypoint()
|
||||
&& timePoint.compareTo(markPassings.last().getTimePoint()) > 0) {
|
||||
// competitor has finished race; use time point of crossing the finish line
|
||||
end = markPassings.last().getTimePoint();
|
||||
} else {
|
||||
if (markPassings.last().getWaypoint() != trackedRace.getRace().getCourse().getLastWaypoint() &&
|
||||
alsoReturnDistanceIfCompetitorHasNotFinishedRace) {
|
||||
end = markPassings.last().getTimePoint();
|
||||
}
|
||||
}
|
||||
return trackedRace.getTrack(competitor).getDistanceTraveled(markPassings.first().getTimePoint(), end);
|
||||
}
|
||||
}
|
||||
|
||||
public Distance getTotalDistanceTraveled(Leaderboard leaderboard, Competitor competitor, TimePoint timePoint) {
|
||||
Distance result = null;
|
||||
for (TrackedRace trackedRace : leaderboard.getTrackedRaces()) {
|
||||
if (Util.contains(trackedRace.getRace().getCompetitors(), competitor)) {
|
||||
Distance distanceSailedInRace = getDistanceTraveled(trackedRace, competitor, timePoint, true);
|
||||
if (distanceSailedInRace != null) {
|
||||
if (result == null) {
|
||||
result = distanceSailedInRace;
|
||||
} else {
|
||||
result = result.add(distanceSailedInRace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Speed getAverageSpeedOverGround(Leaderboard leaderboard, Competitor competitor, TimePoint timePoint, boolean alsoIncludeNonFinishedRaces) {
|
||||
Speed result = null;
|
||||
for (TrackedRace trackedRace : leaderboard.getTrackedRaces()) {
|
||||
if (Util.contains(trackedRace.getRace().getCompetitors(), competitor)) {
|
||||
NavigableSet<MarkPassing> markPassings = trackedRace.getMarkPassings(competitor);
|
||||
if (!markPassings.isEmpty()) {
|
||||
TimePoint from = markPassings.first().getTimePoint();
|
||||
TimePoint to;
|
||||
if (timePoint.after(markPassings.last().getTimePoint()) &&
|
||||
markPassings.last().getWaypoint() == trackedRace.getRace().getCourse().getLastWaypoint()) {
|
||||
// stop counting when competitor finished the race
|
||||
to = markPassings.last().getTimePoint();
|
||||
} else {
|
||||
if (markPassings.last().getWaypoint() != trackedRace.getRace().getCourse().getLastWaypoint() &&
|
||||
timePoint.after(markPassings.last().getTimePoint()) &&
|
||||
!alsoIncludeNonFinishedRaces) {
|
||||
result = null;
|
||||
break;
|
||||
}
|
||||
to = timePoint;
|
||||
}
|
||||
Distance distanceTraveled = trackedRace.getDistanceTraveled(competitor, timePoint);
|
||||
if (distanceTraveled != null) {
|
||||
result = distanceTraveled.inTime(to.asMillis()-from.asMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String cleanSailId(String sailId, Competitor competitor) {
|
||||
if (sailId.matches("^[A-Z]{3}\\s[0-9]*")) {
|
||||
Pattern regex = Pattern.compile("(^[A-Z]{3})\\s([0-9]*)");
|
||||
Matcher regexMatcher = regex.matcher(sailId);
|
||||
try {
|
||||
return regexMatcher.replaceAll("$1$2");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (sailId.matches("^[A-Z]{3}\\S[0-9]*")) {
|
||||
return sailId;
|
||||
} else if (sailId.matches("[0-9]*")){
|
||||
Nationality nationality = competitor.getTeam().getNationality();
|
||||
return (nationality==null ? "" : nationality.getThreeLetterIOCAcronym() + sailId);
|
||||
}
|
||||
return sailId;
|
||||
}
|
||||
|
||||
public void sendDocument(Element element, String fileName) {
|
||||
final Format format = Format.getPrettyFormat();
|
||||
format.setIndent(" ");
|
||||
format.setExpandEmptyElements(true);
|
||||
format.setEncoding("UTF-8");
|
||||
XMLOutputter xmlOutputter = new XMLOutputter(format);
|
||||
|
||||
res.setContentType("text/xml");
|
||||
res.addHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
|
||||
try {
|
||||
xmlOutputter.output(element, res.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected long handleValue(TimePoint timepoint) {
|
||||
if (timepoint != null) {
|
||||
return timepoint.asMillis();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected String getBoatClassName(final Leaderboard leaderboard) {
|
||||
String result = null;
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
result = ((RegattaLeaderboard) leaderboard).getRegatta().getBoatClass().getName();
|
||||
} else {
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
for (Fleet fleet : raceColumn.getFleets()) {
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
result = trackedRace.getRace().getBoatClass().getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void addNamedElementWithValue(Element parent, String newChildName, Integer i) {
|
||||
if (i == null) {
|
||||
addNamedElementWithValue(parent, newChildName, "0");
|
||||
} else {
|
||||
addNamedElementWithValue(parent, newChildName, i.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void addNamedElementWithValue(Element parent, String newChildName, Double dbl) {
|
||||
if (dbl == null) {
|
||||
addNamedElementWithValue(parent, newChildName, "0");
|
||||
} else {
|
||||
addNamedElementWithValue(parent, newChildName, dbl.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void addNamedElementWithValue(Element parent, String newChildName, Long l) {
|
||||
if (l == null) {
|
||||
addNamedElementWithValue(parent, newChildName, "0");
|
||||
} else {
|
||||
addNamedElementWithValue(parent, newChildName, l.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected Element addNamedElementWithValue(Element parent, String newChildName, String value) {
|
||||
final Element newChild = new Element(newChildName);
|
||||
newChild.addContent(value);
|
||||
parent.addContent(newChild);
|
||||
return newChild;
|
||||
}
|
||||
|
||||
protected Element createNamedElementWithValue(String elementName, String value) {
|
||||
final Element element = new Element(elementName);
|
||||
element.addContent(value);
|
||||
return element;
|
||||
}
|
||||
|
||||
protected Element createNamedElementWithValue(String elementName, int value) {
|
||||
final Element element = new Element(elementName);
|
||||
element.addContent(String.valueOf(value));
|
||||
return element;
|
||||
}
|
||||
|
||||
protected Element createNamedElementWithValue(String elementName, double value) {
|
||||
final Element element = new Element(elementName);
|
||||
element.addContent(String.valueOf(value));
|
||||
return element;
|
||||
}
|
||||
|
||||
protected Element createNamedElementWithValue(String elementName, long value) {
|
||||
final Element element = new Element(elementName);
|
||||
element.addContent(String.valueOf(value));
|
||||
return element;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,506 @@
|
||||
package com.sap.sailing.xmlexport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.jdom.Element;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.SpeedWithConfidence;
|
||||
import com.sap.sailing.domain.base.impl.SpeedWithConfidenceImpl;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.LineLengthAndAdvantage;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
/**
|
||||
* Exports all data from a leaderboard into XML format. Format is as follows:
|
||||
*
|
||||
* <pre>
|
||||
* <leaderboard>
|
||||
* <name>XY</name>
|
||||
* <competitor>
|
||||
* <uuid>1234</uuid>
|
||||
* <sail_id></sail_id>
|
||||
* </competitor>
|
||||
*
|
||||
* <race>
|
||||
* <name>R1</name>
|
||||
* <competitor>
|
||||
* <uuid>1234</uuid>
|
||||
* <race_final_rank>1</race_final_rank>
|
||||
* <race_final_score>10</race_final_score>
|
||||
* </competitor>
|
||||
* <leg>
|
||||
* <count>1</count>
|
||||
* <competitor>
|
||||
* <uuid>1234</uuid>
|
||||
* <number_of_jibes>123</number_of_jibes>
|
||||
* </competitor>
|
||||
* </leg>
|
||||
* </race>
|
||||
* </leaderboard>
|
||||
* </pre>
|
||||
*
|
||||
* @author Simon Marcel Pamies
|
||||
*/
|
||||
public class LeaderboardData extends ExportAction {
|
||||
|
||||
private static final String VERY_LIGHT_WIND_DESCRIPTION = "Very Light";
|
||||
private static final String LIGHT_WIND_DESCRIPTION = "Light";
|
||||
private static final String MEDIUM_WIND_DESCRIPTION = "Medium";
|
||||
private static final String STRONG_WIND_DESCRIPTION = "Strong";
|
||||
private static final String VERY_STRONG_WIND_DESCRIPTION = "Very Strong";
|
||||
|
||||
public LeaderboardData(HttpServletRequest req, HttpServletResponse res, RacingEventService service) {
|
||||
super(req, res, service);
|
||||
}
|
||||
|
||||
private Element createLeaderboardXML(Leaderboard leaderboard, List<Element> competitors, List<Element> races, Pair<Double, Vector<String>> leaderboardConfidenceAndErrorMessages) {
|
||||
Element leaderboardElement = new Element("leaderboard");
|
||||
addNamedElementWithValue(leaderboardElement, "name", leaderboard.getName());
|
||||
addNamedElementWithValue(leaderboardElement, "display_name", leaderboard.getDisplayName());
|
||||
addNamedElementWithValue(leaderboardElement, "delay_to_live_in_millis", leaderboard.getDelayToLiveInMillis());
|
||||
addNamedElementWithValue(leaderboardElement, "scoring_scheme", leaderboard.getScoringScheme().getType().name());
|
||||
addNamedElementWithValue(leaderboardElement, "boat_class", getBoatClassName(leaderboard));
|
||||
leaderboardElement.addContent(createTimedXML("last_modification_", leaderboard.getTimePointOfLatestModification()));
|
||||
leaderboardElement.addContent(createDataConfidenceXML(leaderboardConfidenceAndErrorMessages));
|
||||
leaderboardElement.addContent(competitors);
|
||||
leaderboardElement.addContent(races);
|
||||
return leaderboardElement;
|
||||
}
|
||||
|
||||
private List<Element> createTimedXML(String prefix, TimePoint timepoint) {
|
||||
List<Element> timedElements = new ArrayList<Element>();
|
||||
Calendar timedDate = Calendar.getInstance();
|
||||
if (timepoint != null) {
|
||||
timedDate.setTime(timepoint.asDate());
|
||||
|
||||
timedElements.add(createNamedElementWithValue(prefix+"year", timedDate.get(Calendar.YEAR)));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"month", timedDate.get(Calendar.MONTH)));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"day", timedDate.get(Calendar.DAY_OF_MONTH)));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"hour", timedDate.get(Calendar.HOUR_OF_DAY)));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"minute", timedDate.get(Calendar.MINUTE)));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"second", timedDate.get(Calendar.SECOND)));
|
||||
|
||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
|
||||
timedElements.add(createNamedElementWithValue(prefix+"formatted", dateFormatter.format(timedDate.getTime())));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"millis_since_epoch", timepoint.asMillis()));
|
||||
} else {
|
||||
timedElements.add(createNamedElementWithValue(prefix+"year", ""));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"month", ""));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"day", ""));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"hour", ""));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"minute", ""));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"second", ""));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"formatted", ""));
|
||||
timedElements.add(createNamedElementWithValue(prefix+"millis_since_epoch", ""));
|
||||
}
|
||||
return timedElements;
|
||||
}
|
||||
|
||||
public List<Element> createWindXML(String prefix, SpeedWithConfidence<TimePoint> speedWithConfidence) {
|
||||
List<Element> windElements = new ArrayList<Element>();
|
||||
if (speedWithConfidence == null) {
|
||||
speedWithConfidence = new SpeedWithConfidenceImpl<TimePoint>(new KnotSpeedImpl(0.0), 0, MillisecondsTimePoint.now());
|
||||
}
|
||||
windElements.add(createNamedElementWithValue(prefix+"speed_in_knots", speedWithConfidence.getObject().getKnots()));
|
||||
windElements.add(createNamedElementWithValue(prefix+"speed_in_meters_per_second", speedWithConfidence.getObject().getMetersPerSecond()));
|
||||
windElements.add(createNamedElementWithValue(prefix+"speed_in_beaufort", speedWithConfidence.getObject().getBeaufort()));
|
||||
windElements.add(createNamedElementWithValue(prefix+"confidence", speedWithConfidence.getConfidence()));
|
||||
|
||||
double speedInKnots = speedWithConfidence.getObject().getKnots();
|
||||
String windSpeedAsHumanReadableString = "";
|
||||
String windSpeedAsInterval = "";
|
||||
if (speedInKnots <= 4) {
|
||||
windSpeedAsHumanReadableString = VERY_LIGHT_WIND_DESCRIPTION;
|
||||
windSpeedAsInterval = "0-4kn";
|
||||
} else if (speedInKnots > 4 && speedInKnots <= 8) {
|
||||
windSpeedAsHumanReadableString = LIGHT_WIND_DESCRIPTION;
|
||||
windSpeedAsInterval = "4-8kn";
|
||||
} else if (speedInKnots > 8 && speedInKnots <= 14) {
|
||||
windSpeedAsHumanReadableString = MEDIUM_WIND_DESCRIPTION;
|
||||
windSpeedAsInterval = "8-14kn";
|
||||
} else if (speedInKnots > 14 && speedInKnots <= 20) {
|
||||
windSpeedAsHumanReadableString = STRONG_WIND_DESCRIPTION;
|
||||
windSpeedAsInterval = "14-20kn";
|
||||
} else if (speedInKnots > 20) {
|
||||
windSpeedAsHumanReadableString = VERY_STRONG_WIND_DESCRIPTION;
|
||||
windSpeedAsInterval = "20-"+speedInKnots+"kn";
|
||||
}
|
||||
windElements.add(createNamedElementWithValue(prefix+"human_readable", windSpeedAsHumanReadableString));
|
||||
windElements.add(createNamedElementWithValue(prefix+"knots_interval", windSpeedAsInterval));
|
||||
return windElements;
|
||||
}
|
||||
|
||||
private Element createRaceXML(TrackedRace race, Fleet fleet, List<Element> legs, RaceColumn column, Leaderboard leaderboard, int sameDayGroupIndex, int raceCounter, Pair<Double, Vector<String>> raceConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException {
|
||||
Element raceElement = new Element("race");
|
||||
addNamedElementWithValue(raceElement, "name", cleanRaceName(race.getRace().getName()));
|
||||
addNamedElementWithValue(raceElement, "race_index_in_leaderboard", raceCounter);
|
||||
addNamedElementWithValue(raceElement, "fleet_name", fleet.getName());
|
||||
addNamedElementWithValue(raceElement, "same_day_index", sameDayGroupIndex);
|
||||
raceElement.addContent(createDataConfidenceXML(raceConfidenceAndErrorMessages));
|
||||
|
||||
addNamedElementWithValue(raceElement, "delay_to_live_in_millis", race.getDelayToLiveInMillis());
|
||||
|
||||
addNamedElementWithValue(raceElement, "timepoint_of_last_event_as_millis", handleValue(race.getTimePointOfLastEvent()));
|
||||
addNamedElementWithValue(raceElement, "timepoint_of_newest_event_as_millis", handleValue(race.getTimePointOfNewestEvent()));
|
||||
addNamedElementWithValue(raceElement, "timepoint_of_oldest_event_as_millis", handleValue(race.getTimePointOfOldestEvent()));
|
||||
|
||||
raceElement.addContent(createTimedXML("start_time_", race.getStartOfRace()));
|
||||
raceElement.addContent(createTimedXML("end_time_", race.getEndOfRace()));
|
||||
addNamedElementWithValue(raceElement, "start_of_tracking_time_as_millis", handleValue(race.getStartOfTracking()));
|
||||
addNamedElementWithValue(raceElement, "end_of_tracking_time_as_millis", handleValue(race.getEndOfTracking()));
|
||||
|
||||
addNamedElementWithValue(raceElement, "course_length_in_meters", race.getCourseLength().getMeters());
|
||||
|
||||
raceElement.addContent(createWindXML("wind_", race.getAverageWindSpeedWithConfidence(/*resolutionInMillis*/ 5*60*1000)));
|
||||
|
||||
final List<Competitor> allCompetitors = race.getCompetitorsFromBestToWorst(/*timePoint*/ race.getEndOfRace());
|
||||
addNamedElementWithValue(raceElement, "race_participant_count", allCompetitors.size());
|
||||
|
||||
int raceRank = 0;
|
||||
for (Competitor competitor : allCompetitors) {
|
||||
Element competitorElement = createCompetitorXML(competitor, leaderboard, /*shortVersion*/ true, null);
|
||||
Element competitorRaceDataElement = new Element("competitor_race_data");
|
||||
LineLengthAndAdvantage start = race.getStartLine(race.getStartOfTracking());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "distance_to_start_line_on_race_start_in_meters", race.getDistanceToStartLine(competitor, race.getStartOfRace()).getMeters());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "distance_from_starboard_side_of_start_line_when_passing_start_in_meters", race.getDistanceFromStarboardSideOfStartLineWhenPassingStart(competitor).getMeters());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "speed_when_crossing_start_line_in_knots", race.getSpeedWhenCrossingStartLine(competitor).getKnots());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "start_advantage_in_meters", start.getAdvantage().getMeters());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "speed_on_start_signal_of_race_in_knots", race.getTrack(competitor).getEstimatedSpeed(race.getStartOfRace()).getKnots());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "advantageous_side_while_approaching_start_line", start.getAdvantageousSideWhileApproachingLine().name());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "distance_traveled_in_meters", race.getDistanceTraveled(competitor, race.getEndOfRace()).getMeters());
|
||||
addNamedElementWithValue(competitorRaceDataElement, "final_race_rank", ++raceRank);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "final_race_score", leaderboard.getScoringScheme().getScoreForRank(column, competitor, raceRank, new Callable<Integer>() {
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
return allCompetitors.size();
|
||||
}
|
||||
}));
|
||||
Distance averageCrossTrackError = race.getAverageCrossTrackError(competitor, race.getEndOfRace(), /*waitForLatestAnalysis*/ false);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "average_cross_track_error_in_meters", averageCrossTrackError != null ? averageCrossTrackError.getMeters() : -1.0);
|
||||
addNamedElementWithValue(competitorRaceDataElement, "max_points_reason", leaderboard.getMaxPointsReason(competitor, column, race.getEndOfRace()).toString());
|
||||
competitorElement.addContent(competitorRaceDataElement);
|
||||
raceElement.addContent(competitorElement);
|
||||
}
|
||||
|
||||
raceElement.addContent(legs);
|
||||
return raceElement;
|
||||
}
|
||||
|
||||
private Element createCompetitorXML(Competitor competitor, Leaderboard leaderboard, boolean shortVersion, Pair<Double, Vector<String>> competitorConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException {
|
||||
Element competitorElement = new Element("competitor");
|
||||
addNamedElementWithValue(competitorElement, "uuid", competitor.getId().toString());
|
||||
addNamedElementWithValue(competitorElement, "name", competitor.getName());
|
||||
|
||||
if (shortVersion)
|
||||
return competitorElement;
|
||||
|
||||
createDataConfidenceXML(competitorConfidenceAndErrorMessages);
|
||||
|
||||
if (competitor.getBoat() != null) {
|
||||
addNamedElementWithValue(competitorElement, "sail_id", cleanSailId(competitor.getBoat().getSailID(), competitor));
|
||||
addNamedElementWithValue(competitorElement, "boat_class", competitor.getBoat().getBoatClass().getName());
|
||||
addNamedElementWithValue(competitorElement, "boat_name", competitor.getBoat().getName());
|
||||
} else {
|
||||
addNamedElementWithValue(competitorElement, "sail_id", "");
|
||||
addNamedElementWithValue(competitorElement, "boat_class", "");
|
||||
addNamedElementWithValue(competitorElement, "boat_name", "");
|
||||
}
|
||||
|
||||
if (competitor.getTeam() != null && competitor.getTeam().getNationality() != null) {
|
||||
addNamedElementWithValue(competitorElement, "nationality_name", competitor.getTeam().getNationality().getName());
|
||||
addNamedElementWithValue(competitorElement, "nationality_ioc", competitor.getTeam().getNationality().getThreeLetterIOCAcronym());
|
||||
} else {
|
||||
addNamedElementWithValue(competitorElement, "nationality_name", "");
|
||||
addNamedElementWithValue(competitorElement, "nationality_ioc", "");
|
||||
}
|
||||
|
||||
if (leaderboard.getTimePointOfLatestModification() != null) {
|
||||
TimePoint timePointOfLatestModification = leaderboard.getTimePointOfLatestModification();
|
||||
Long totalTimeSailed = leaderboard.getTotalTimeSailedInMilliseconds(competitor, timePointOfLatestModification);
|
||||
addNamedElementWithValue(competitorElement, "total_time_sailed_in_milliseconds", totalTimeSailed);
|
||||
addNamedElementWithValue(competitorElement, "total_time_sailed_including_non_finished_races_in_milliseconds", getTotalTimeSailedInMilliseconds(competitor, timePointOfLatestModification, true));
|
||||
Distance totalDistanceSailed = leaderboard.getTotalDistanceTraveled(competitor, timePointOfLatestModification);
|
||||
addNamedElementWithValue(competitorElement, "total_distance_sailed_in_meters", totalDistanceSailed != null ? totalDistanceSailed.getMeters() : 0);
|
||||
addNamedElementWithValue(competitorElement, "total_distance_sailed_including_non_finished_races_in_meters", getTotalDistanceTraveled(leaderboard, competitor, timePointOfLatestModification).getMeters());
|
||||
addNamedElementWithValue(competitorElement, "maximum_speed_over_ground_in_knots", leaderboard.getMaximumSpeedOverGround(competitor, timePointOfLatestModification).getB().getKnots());
|
||||
Speed averageSpeed = leaderboard.getAverageSpeedOverGround(competitor, timePointOfLatestModification);
|
||||
addNamedElementWithValue(competitorElement, "average_speed_over_ground_from_start_mark_passing_in_knots", averageSpeed != null ? averageSpeed.getKnots() : 0);
|
||||
addNamedElementWithValue(competitorElement, "average_speed_over_ground_including_non_finished_races_in_knots", getAverageSpeedOverGround(leaderboard, competitor, timePointOfLatestModification, true).getKnots());
|
||||
|
||||
addNamedElementWithValue(competitorElement, "overall_rank", leaderboard.getTotalRankOfCompetitor(competitor, timePointOfLatestModification));
|
||||
addNamedElementWithValue(competitorElement, "overall_score", leaderboard.getTotalPoints(competitor, timePointOfLatestModification));
|
||||
} else {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
addNamedElementWithValue(competitorElement, "total_time_sailed_in_milliseconds", leaderboard.getTotalTimeSailedInMilliseconds(competitor, now));
|
||||
addNamedElementWithValue(competitorElement, "total_time_sailed_including_non_finished_races_in_milliseconds", getTotalTimeSailedInMilliseconds(competitor, now, true));
|
||||
addNamedElementWithValue(competitorElement, "total_distance_sailed_in_meters", leaderboard.getTotalDistanceTraveled(competitor, now).getMeters());
|
||||
addNamedElementWithValue(competitorElement, "total_distance_sailed_including_non_finished_races_in_meters", getTotalDistanceTraveled(leaderboard, competitor, now).getMeters());
|
||||
addNamedElementWithValue(competitorElement, "maximum_speed_over_ground_in_knots", leaderboard.getMaximumSpeedOverGround(competitor, now).getB().getKnots());
|
||||
Speed averageSpeed = leaderboard.getAverageSpeedOverGround(competitor, now);
|
||||
addNamedElementWithValue(competitorElement, "average_speed_over_ground_from_start_mark_passing_in_knots", averageSpeed != null ? averageSpeed.getKnots() : 0);
|
||||
addNamedElementWithValue(competitorElement, "average_speed_over_ground_including_non_finished_races_in_knots", getAverageSpeedOverGround(leaderboard, competitor, now, true).getKnots());
|
||||
|
||||
addNamedElementWithValue(competitorElement, "overall_rank", leaderboard.getTotalRankOfCompetitor(competitor, now));
|
||||
addNamedElementWithValue(competitorElement, "overall_score", leaderboard.getTotalPoints(competitor, now));
|
||||
}
|
||||
return competitorElement;
|
||||
}
|
||||
|
||||
private Element createLegXML(TrackedLeg trackedLeg, Leaderboard leaderboard, int legCounter, Pair<Double, Vector<String>> raceConfidenceAndErrorMessages, Pair<Double, Vector<String>> legConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException {
|
||||
Leg leg = trackedLeg.getLeg();
|
||||
Element legElement = new Element("leg");
|
||||
legElement.addContent(createDataConfidenceXML(legConfidenceAndErrorMessages));
|
||||
addNamedElementWithValue(legElement, "position", legCounter);
|
||||
addNamedElementWithValue(legElement, "mark_from", leg.getFrom().getName());
|
||||
addNamedElementWithValue(legElement, "mark_to", leg.getTo().getName());
|
||||
addNamedElementWithValue(legElement, "leg_type", trackedLeg.getLegType(trackedLeg.getTrackedRace().getStartOfRace()).name());
|
||||
|
||||
for (Competitor competitor : trackedLeg.getTrackedRace().getCompetitorsFromBestToWorst(/*timePoint*/ trackedLeg.getTrackedRace().getEndOfRace())) {
|
||||
Element competitorElement = createCompetitorXML(competitor, leaderboard, /*shortVersion*/ true, null);
|
||||
Element competitorLegDataElement = new Element("competitor_leg_data");
|
||||
TrackedLegOfCompetitor competitorLeg = trackedLeg.getTrackedLeg(competitor);
|
||||
|
||||
/* if there is no start time then ignore all data of this leg */
|
||||
if (competitorLeg.getStartTime() == null || competitorLeg.getFinishTime() == null) {
|
||||
competitorElement.addContent(competitorLegDataElement);
|
||||
continue;
|
||||
}
|
||||
|
||||
TimePoint legFinishTime = competitorLeg.getFinishTime();
|
||||
competitorLegDataElement.addContent(createTimedXML("leg_started_time_", competitorLeg.getStartTime()));
|
||||
Pair<GPSFixMoving, Speed> maximumSpeed = competitorLeg.getMaximumSpeedOverGround(legFinishTime);
|
||||
addNamedElementWithValue(competitorLegDataElement, "maximum_speed_over_ground_in_knots", maximumSpeed != null ? maximumSpeed.getB().getKnots() : -1);
|
||||
addNamedElementWithValue(competitorLegDataElement, "average_velocity_made_good_in_knots", competitorLeg.getAverageVelocityMadeGood(legFinishTime).getKnots());
|
||||
addNamedElementWithValue(competitorLegDataElement, "leg_finished_time_as_millis", handleValue(legFinishTime));
|
||||
addNamedElementWithValue(competitorLegDataElement, "total_race_time_elapsed_as_millis", handleValue(legFinishTime)-handleValue(trackedLeg.getTrackedRace().getStartOfRace()));
|
||||
addNamedElementWithValue(competitorLegDataElement, "time_spend_in_this_leg_as_millis", competitorLeg.getTimeInMilliSeconds(legFinishTime));
|
||||
addNamedElementWithValue(competitorLegDataElement, "gap_to_leader_at_finish_in_seconds", competitorLeg.getGapToLeaderInSeconds(legFinishTime));
|
||||
addNamedElementWithValue(competitorLegDataElement, "windward_distance_to_overall_leader_that_has_finished_this_leg_in_meters", competitorLeg.getWindwardDistanceToOverallLeader(legFinishTime).getMeters());
|
||||
addNamedElementWithValue(competitorLegDataElement, "distance_traveled_in_meters", competitorLeg.getDistanceTraveled(legFinishTime).getMeters());
|
||||
addNamedElementWithValue(competitorLegDataElement, "average_speed_over_ground_in_knots", competitorLeg.getAverageSpeedOverGround(legFinishTime).getKnots());
|
||||
addNamedElementWithValue(competitorLegDataElement, "number_of_jibes", competitorLeg.getNumberOfJibes(legFinishTime));
|
||||
addNamedElementWithValue(competitorLegDataElement, "number_of_tacks", competitorLeg.getNumberOfTacks(legFinishTime));
|
||||
addNamedElementWithValue(competitorLegDataElement, "number_of_penalty_circles", competitorLeg.getNumberOfPenaltyCircles(legFinishTime));
|
||||
|
||||
addNamedElementWithValue(competitorLegDataElement, "leg_rank_at_leg_start", competitorLeg.getRank(competitorLeg.getStartTime()));
|
||||
addNamedElementWithValue(competitorLegDataElement, "leg_rank_at_leg_finish", competitorLeg.getRank(legFinishTime));
|
||||
addNamedElementWithValue(competitorLegDataElement, "rank_gain_for_this_leg_between_start_and_finish", competitorLeg.getRank(competitorLeg.getStartTime())-competitorLeg.getRank(legFinishTime));
|
||||
|
||||
List<Maneuver> maneuvers = competitorLeg.getManeuvers(legFinishTime, /*waitForLatest*/false);
|
||||
addNamedElementWithValue(competitorLegDataElement, "maneuver_count", maneuvers.size());
|
||||
Element maneuversElement = new Element("maneuvers");
|
||||
for (Maneuver man : maneuvers) {
|
||||
Element maneuverInformation = new Element("maneuver");
|
||||
addNamedElementWithValue(maneuverInformation, "type", man.getType().toString());
|
||||
addNamedElementWithValue(maneuverInformation, "direction_change_in_degrees", man.getDirectionChangeInDegrees());
|
||||
Distance maneuverLoss = man.getManeuverLoss();
|
||||
addNamedElementWithValue(maneuverInformation, "loss_in_meters", maneuverLoss != null ? maneuverLoss.getMeters() : 0.0);
|
||||
addNamedElementWithValue(maneuverInformation, "speed_before_in_knots", man.getSpeedWithBearingBefore().getKnots());
|
||||
addNamedElementWithValue(maneuverInformation, "speed_after_in_knots", man.getSpeedWithBearingAfter().getKnots());
|
||||
maneuversElement.addContent(maneuverInformation);
|
||||
}
|
||||
competitorLegDataElement.addContent(maneuversElement);
|
||||
|
||||
Distance averageCrossTrackError = competitorLeg.getAverageCrossTrackError(legFinishTime, /*waitForLatestAnalysis*/ false);
|
||||
addNamedElementWithValue(competitorLegDataElement, "average_cross_track_error_in_meters", averageCrossTrackError != null ? averageCrossTrackError.getMeters() : -1);
|
||||
|
||||
competitorElement.addContent(competitorLegDataElement);
|
||||
legElement.addContent(competitorElement);
|
||||
}
|
||||
return legElement;
|
||||
}
|
||||
|
||||
private Element createDataConfidenceXML(Pair<Double, Vector<String>> confidenceAndMessages) {
|
||||
Element confidenceDataElement = new Element("confidence");
|
||||
addNamedElementWithValue(confidenceDataElement, "simple_confidence_value", confidenceAndMessages.getA().doubleValue());
|
||||
Element messagesElement = new Element("messages");
|
||||
for (String message : confidenceAndMessages.getB()) {
|
||||
addNamedElementWithValue(messagesElement, "message", message);
|
||||
}
|
||||
confidenceDataElement.addContent(messagesElement);
|
||||
return confidenceDataElement;
|
||||
}
|
||||
|
||||
private Pair<Double, Vector<String>> checkData(TrackedLeg leg) throws Exception {
|
||||
double simpleConfidence = 1.0; Vector<String> messages = new Vector<String>();
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
for (TrackedLegOfCompetitor competitorLeg : leg.getTrackedLegsOfCompetitors()) {
|
||||
if (!competitorLeg.hasFinishedLeg(now) || competitorLeg.getFinishTime() == null) {
|
||||
messages.add("Competitor " + competitorLeg.getCompetitor().getName() + " has not finished this leg!");
|
||||
simpleConfidence -= 0.08;
|
||||
}
|
||||
if (!competitorLeg.hasStartedLeg(now) || competitorLeg.getStartTime() == null) {
|
||||
messages.add("Competitor " + competitorLeg.getCompetitor().getName() + " has not started this leg!");
|
||||
simpleConfidence -= 0.08;
|
||||
}
|
||||
if (competitorLeg.getMaximumSpeedOverGround(now) == null) {
|
||||
messages.add("Competitor " + competitorLeg.getCompetitor().getName() + " has no maximum speed for this leg!");
|
||||
simpleConfidence -= 0.05;
|
||||
}
|
||||
if (competitorLeg.getAverageCrossTrackError(now, /*waitForLatestAnalysis*/ false) == null) {
|
||||
messages.add("Competitor " + competitorLeg.getCompetitor().getName() + " has no average cross track error for this leg!");
|
||||
simpleConfidence -= 0.02;
|
||||
}
|
||||
}
|
||||
return new Pair<Double, Vector<String>>(simpleConfidence, messages);
|
||||
}
|
||||
|
||||
private Pair<Double, Vector<String>> checkData(TrackedRace race) throws Exception {
|
||||
double simpleConfidence = 1.0; Vector<String> messages = new Vector<String>();
|
||||
TimePoint dateAtYear2000 = new MillisecondsTimePoint(946681200000l);
|
||||
if (race.getStartOfRace() == null || race.getStartOfRace().before(dateAtYear2000)) {
|
||||
messages.add("Start time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (race.getEndOfRace() == null || race.getEndOfRace().before(dateAtYear2000)) {
|
||||
messages.add("End time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (race.getStartOfTracking() == null || race.getStartOfTracking().before(dateAtYear2000)) {
|
||||
messages.add("Start tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 0.2;
|
||||
}
|
||||
if (race.getEndOfTracking() == null || race.getEndOfTracking().before(dateAtYear2000)) {
|
||||
messages.add("End tracking time of race " + race.getRaceIdentifier().getRaceName() + " is either null or not valid!");
|
||||
simpleConfidence -= 0.2;
|
||||
}
|
||||
return new Pair<Double, Vector<String>>(simpleConfidence, messages);
|
||||
}
|
||||
|
||||
private Pair<Double, Vector<String>> checkData(Competitor competitor) throws Exception {
|
||||
double simpleConfidence = 1.0; Vector<String> messages = new Vector<String>();
|
||||
if (competitor.getName() == null || competitor.getName().equals("")) {
|
||||
messages.add("Competitor " + competitor.getId() + " has no name!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (competitor.getBoat() == null || competitor.getBoat().getSailID() == null || competitor.getBoat().getSailID().equals("")) {
|
||||
messages.add("Competitor " + competitor.getId() + " has no sail id that can be used!");
|
||||
simpleConfidence -= 1;
|
||||
}
|
||||
if (competitor.getTeam() == null || competitor.getTeam().getNationality() == null) {
|
||||
messages.add("Either team for "+ competitor.getId() + " is null or nationality could not be determined");
|
||||
simpleConfidence -= 0.2;
|
||||
}
|
||||
return new Pair<Double, Vector<String>>(simpleConfidence, messages);
|
||||
}
|
||||
|
||||
private Pair<Double, Vector<String>> checkData(Leaderboard leaderboard) throws Exception {
|
||||
double simpleConfidence = 1.0; Vector<String> messages = new Vector<String>();
|
||||
int raceColumnCount = 0; int attachedRaceToColumnCount = 0;
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
if (raceColumn.hasTrackedRaces()) {
|
||||
attachedRaceToColumnCount++;
|
||||
}
|
||||
raceColumnCount++;
|
||||
}
|
||||
if (raceColumnCount == 0) {
|
||||
messages.add("Could not find any race columns or none of the race columns has tracked races attached!");
|
||||
simpleConfidence -= 1.0;
|
||||
}
|
||||
if (attachedRaceToColumnCount < raceColumnCount) {
|
||||
messages.add("Not all race columns contain attached races! Data being aggregated over all races could be wrong!");
|
||||
simpleConfidence -= 0.3;
|
||||
}
|
||||
int competitorCount = 0;
|
||||
for (Iterator<Competitor> iterator = leaderboard.getAllCompetitors().iterator(); iterator.hasNext();) {
|
||||
iterator.next();
|
||||
competitorCount++;
|
||||
}
|
||||
if (competitorCount == 0) {
|
||||
messages.add("Could not find any competitors in this leaderboard!");
|
||||
simpleConfidence -= 1.0;
|
||||
}
|
||||
TimePoint dateAtYear2000 = new MillisecondsTimePoint(946681200000l);
|
||||
if (leaderboard.getTimePointOfLatestModification().before(dateAtYear2000)) {
|
||||
messages.add("The time point of the last modification for this leaderboard is very old.");
|
||||
simpleConfidence -= 0.4;
|
||||
}
|
||||
return new Pair<Double, Vector<String>>(simpleConfidence, messages);
|
||||
}
|
||||
|
||||
private int getSameDayGroupIndex(TrackedRace currentRace, TrackedRace raceBefore) {
|
||||
if (raceBefore != null && !raceBefore.equals(currentRace)) {
|
||||
if (currentRace != null && currentRace.getStartOfRace() != null && raceBefore.getStartOfRace() != null) {
|
||||
Calendar timedDateForCurrentRace = Calendar.getInstance();
|
||||
timedDateForCurrentRace.setTime(currentRace.getStartOfRace().asDate());
|
||||
String formattedCurrent = new SimpleDateFormat("dd.MM.yyyy").format(timedDateForCurrentRace.getTime());
|
||||
|
||||
Calendar timedDateForRaceBefore = Calendar.getInstance();
|
||||
timedDateForRaceBefore.setTime(raceBefore.getStartOfRace().asDate());
|
||||
String formattedBefore = new SimpleDateFormat("dd.MM.yyyy").format(timedDateForRaceBefore.getTime());
|
||||
|
||||
if (formattedCurrent.equals(formattedBefore)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void perform() throws Exception {
|
||||
final Leaderboard leaderboard = getLeaderboard();
|
||||
Pair<Double, Vector<String>> leaderboardConfidenceAndErrorMessages = checkData(leaderboard);
|
||||
|
||||
final List<Element> racesElements = new ArrayList<Element>();
|
||||
final List<Element> competitorElements = new ArrayList<Element>();
|
||||
|
||||
for (Competitor competitor : leaderboard.getAllCompetitors()) {
|
||||
Pair<Double, Vector<String>> competitorConfidenceAndErrorMessages = checkData(competitor);
|
||||
competitorElements.add(createCompetitorXML(competitor, leaderboard, /*shortVersion*/ false, competitorConfidenceAndErrorMessages));
|
||||
}
|
||||
|
||||
TrackedRace raceBefore = null; int sameDayGroupIndex = 0;
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
for (Fleet fleet : raceColumn.getFleets()) {
|
||||
sameDayGroupIndex += getSameDayGroupIndex(raceColumn.getTrackedRace(fleet), raceBefore);
|
||||
int raceCounter = 0;
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRace != null && trackedRace.hasGPSData()) {
|
||||
raceCounter++;
|
||||
Pair<Double, Vector<String>> raceConfidenceAndErrorMessages = checkData(trackedRace);
|
||||
final List<Element> legs = new ArrayList<Element>();
|
||||
int legCounter = 0;
|
||||
for (TrackedLeg leg : trackedRace.getTrackedLegs()) {
|
||||
Pair<Double, Vector<String>> legConfidenceAndErrorMessages = checkData(leg);
|
||||
legs.add(createLegXML(leg, leaderboard, ++legCounter, raceConfidenceAndErrorMessages, legConfidenceAndErrorMessages));
|
||||
}
|
||||
racesElements.add(createRaceXML(trackedRace, fleet, legs, raceColumn, leaderboard, sameDayGroupIndex, raceCounter, raceConfidenceAndErrorMessages));
|
||||
raceBefore = trackedRace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendDocument(createLeaderboardXML(leaderboard, competitorElements, racesElements, leaderboardConfidenceAndErrorMessages), leaderboard.getName() + ".xml");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.sap.sailing.xmlexport;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
|
||||
|
||||
public class XmlExportServlet extends SailingServerHttpServlet {
|
||||
private static final long serialVersionUID = -6849138354942569249L;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
|
||||
final String action = req.getParameter("domain");
|
||||
try {
|
||||
if ((action != null) && !"".equals(action)) {
|
||||
if ("leaderboard".equalsIgnoreCase(action)) {
|
||||
final LeaderboardData leaderboardData = new LeaderboardData(req, res, getService());
|
||||
leaderboardData.perform();
|
||||
return;
|
||||
}
|
||||
throw new ServletException("Unknown domain " + action);
|
||||
}
|
||||
throw new ServletException("Please use the domain= parameter to specify a domain that'll be exported.");
|
||||
} catch (Exception e) {
|
||||
throw (new ServletException(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user