Merge remote-tracking branch 'server/master'

This commit is contained in:
Axel Uhl
2012-11-15 15:43:15 +01:00
10 changed files with 118 additions and 66 deletions
@@ -429,4 +429,6 @@ public interface StringMessages extends Messages {
String averageManeuverLossInMeters();
String averageTackLossInMeters();
String averageJibeLossInMeters();
String legend();
String live();
}
@@ -429,4 +429,6 @@ errorUpdatingIsMedalRace=Error updating the medal race setting: {0}
maneuverLoss=Maneuver loss
averageManeuverLossInMeters=\u2205 Maneuver Loss
averageTackLossInMeters=\u2205 Tack Loss
averageJibeLossInMeters=\u2205 Jibe Loss
averageJibeLossInMeters=\u2205 Jibe Loss
legend=Legend
live=live
@@ -430,4 +430,6 @@ errorUpdatingIsMedalRace=Fehler beim Ändern der Medaillenrennen-Einstellung: {0
maneuverLoss=Manöververlust
averageManeuverLossInMeters=\u2205 Manöververlust
averageTackLossInMeters=\u2205 Wendeverlust
averageJibeLossInMeters=\u2205 Halseverlust
averageJibeLossInMeters=\u2205 Halseverlust
legend=Legende
live=live
@@ -8,6 +8,7 @@ import java.util.Map;
import com.google.gwt.cell.client.SafeHtmlCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
@@ -15,8 +16,11 @@ import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
@@ -25,7 +29,6 @@ import com.sap.sailing.domain.common.Color;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.gwt.ui.adminconsole.LeaderboardConfigPanel.AnchorCell;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.HasWelcomeWidget;
@@ -39,7 +42,6 @@ import com.sap.sailing.gwt.ui.shared.RaceDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.panels.BreadcrumbPanel;
import com.sap.sailing.gwt.ui.shared.panels.WelcomeWidget;
public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget {
@@ -71,8 +73,17 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
private static final AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class);
private static final TextWithClassTemplate TEXTTEMPLATE = GWT.create(TextWithClassTemplate.class);
private static final ColorBoxTemplate COLORBOXTEMPLATE = GWT.create(ColorBoxTemplate.class);
private static final String STYLE_NAME_PREFIX = "leaderboardGroupPanel-";
private static final String STYLE_NAME_PREFIX = "leaderboardGroupPanel-";
private static final String STYLE_INACTIVE_RACE = STYLE_NAME_PREFIX + "InactiveRace";
private static final String STYLE_ACTIVE_RACE = STYLE_NAME_PREFIX + "ActiveRace";
private static final String STYLE_LIVE_RACE = STYLE_NAME_PREFIX + "LiveRace";
private static final String STYLE_ACTIVE_BUTTON = STYLE_NAME_PREFIX + "ActiveButton";
private static final String STYLE_ACTIVE_LEADERBOARD = STYLE_NAME_PREFIX + "ActiveLeaderboard";
private static final String STYLE_LEGEND = STYLE_NAME_PREFIX + "Legend";
private enum RacesRenderStrategy { DEFAULT, ESS40 };
private final SailingServiceAsync sailingService;
private final StringMessages stringMessages;
private final ErrorReporter errorReporter;
@@ -87,6 +98,8 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
private final boolean isEmbedded;
private final boolean showRaceDetails;
private RacesRenderStrategy racesRenderStrategy = RacesRenderStrategy.DEFAULT;
public LeaderboardGroupPanel(SailingServiceAsync sailingService, StringMessages stringConstants,
ErrorReporter errorReporter, final String groupName, String root, String viewMode, boolean embedded, boolean showRaceDetails) {
super();
@@ -129,7 +142,7 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
for(RegattaDTO regattaDTO: regattaDTOs) {
regattasByName.put(regattaDTO.name, regattaDTO);
}
buildGUI();
createdPageContent();
}
@Override
@@ -138,7 +151,7 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
}
});
} else {
buildGUI();
createdPageContent();
}
} else {
errorReporter.reportError(stringMessages.noLeaderboardGroupWithNameFound(leaderboardGroupName));
@@ -151,14 +164,8 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
});
}
private void buildGUI() {
private void createdPageContent() {
if (!isEmbedded) {
// Create breadcrumb panel
BreadcrumbPanel breadcrumbPanel = createBreadcrumbPanel();
if (breadcrumbPanel != null) {
mainPanel.add(breadcrumbPanel);
}
// leaderboard group details GUI
Label groupNameLabel = new Label(leaderboardGroup.name + ":");
groupNameLabel.setStyleName(STYLE_NAME_PREFIX + "GroupName");
mainPanel.add(groupNameLabel);
@@ -168,7 +175,6 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
leaderboardGroupDescriptionLabel.setStyleName(STYLE_NAME_PREFIX + "GroupDescription");
mainPanel.add(leaderboardGroupDescriptionLabel);
// leaderboards UI
Label leaderboardsTableLabel = new Label(stringMessages.leaderboards());
leaderboardsTableLabel.setStyleName(STYLE_NAME_PREFIX + "LeaderboardsTableLabel");
mainPanel.add(leaderboardsTableLabel);
@@ -181,8 +187,10 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
+ "&displayName=" + stringMessages.overallStandings()
+ "&leaderboardGroupName=" + leaderboardGroup.name + "&root=" + root
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
HTML overallLeaderboardAnchor = new HTML(getAnchor(link, stringMessages.overallStandings(), "ActiveButton overallStandings"));
mainPanel.add(overallLeaderboardAnchor);
Anchor overallStandingsLink = new Anchor(stringMessages.overallStandings(), true, link);
overallStandingsLink.setStyleName(STYLE_ACTIVE_BUTTON);
overallStandingsLink.addStyleName("overallStandings");
mainPanel.add(overallStandingsLink);
}
}
SafeHtmlCell leaderboardNameCell = new SafeHtmlCell();
@@ -213,7 +221,7 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
+ (isEmbedded ? "&embedded=true" : "")
+ "&leaderboardGroupName=" + leaderboardGroup.name + "&root=" + root
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
return getAnchor(link, stringMessages.overview(), /* style */ "ActiveLeaderboard");
return getAnchor(link, stringMessages.overview(), STYLE_ACTIVE_LEADERBOARD);
}
};
@@ -228,7 +236,12 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
racesCell) {
@Override
public SafeHtml getValue(StrippedLeaderboardDTO leaderboard) {
return leaderboardRacesToHtml(leaderboard);
switch(racesRenderStrategy) {
case DEFAULT: return leaderboardRacesToHtml(leaderboard);
case ESS40: ess40LeaderboardRacesToHtml(leaderboard);
}
return null;
}
};
leaderboardsTable.addColumn(racesColumn, stringMessages.races());
@@ -239,6 +252,31 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
leaderboardsTable.setRowData(leaderboardGroup.getLeaderboards());
}
mainPanel.add(leaderboardsTable);
// legend
if(!isEmbedded) {
HorizontalPanel legendPanel = new HorizontalPanel();
legendPanel.setStyleName(STYLE_LEGEND);
legendPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
legendPanel.setSpacing(5);
mainPanel.add(legendPanel);
Label legendLabel = new Label(stringMessages.legend() + ":");
legendLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
legendPanel.add(legendLabel);
Label inactiveRace = new Label(stringMessages.untracked());
inactiveRace.setStyleName(STYLE_INACTIVE_RACE);
legendPanel.add(inactiveRace);
Label activeRace = new Label(stringMessages.tracked());
activeRace.setStyleName(STYLE_ACTIVE_RACE);
legendPanel.add(activeRace);
Label liveRace = new Label(stringMessages.live());
liveRace.setStyleName(STYLE_LIVE_RACE);
legendPanel.add(liveRace);
}
}
private String shortenLeaderboardName(String prefixToCut, String leaderboardName) {
@@ -268,6 +306,24 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
return b.toSafeHtml();
}
private SafeHtml ess40LeaderboardRacesToHtml(StrippedLeaderboardDTO leaderboard) {
SafeHtmlBuilder b = new SafeHtmlBuilder();
if (leaderboard.isRegattaLeaderboard && leaderboard.regattaName != null) {
RegattaDTO regatta = regattasByName.get(leaderboard.regattaName);
boolean renderSeriesName = Util.size(regatta.series) > 1;
for (SeriesDTO series : regatta.series) {
b.appendHtmlConstant("<div>");
renderSeriesToHtml(leaderboard, series, renderSeriesName, b);
b.appendHtmlConstant("<div style=\"clear:both;\"></div>");
b.appendHtmlConstant("</div>");
}
} else {
List<RaceColumnDTO> raceColumns = leaderboard.getRaceList();
renderRacesToHTml(leaderboard, raceColumns, new FleetDTO("Default", 0, null), b);
}
return b.toSafeHtml();
}
private void renderSeriesToHtml(StrippedLeaderboardDTO leaderboard, SeriesDTO series, boolean renderSeriesName, SafeHtmlBuilder b) {
boolean hasMultipleFleets = series.getFleets().size() > 1;
Map<String, List<RaceColumnDTO>> racesOrderedByFleets = getRacesOrderedByFleets(leaderboard);
@@ -324,13 +380,13 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
link += "&viewMode=" + viewMode;
}
if (race.trackedRace.hasGPSData && race.trackedRace.hasWindData) {
b.append(getAnchor(link, linkText, /* style */ "ActiveRace"));
b.append(getAnchor(link, linkText, STYLE_ACTIVE_RACE));
} else {
b.append(TEXTTEMPLATE.textWithClass(linkText, STYLE_NAME_PREFIX + "InactiveRace"));
b.append(TEXTTEMPLATE.textWithClass(linkText, STYLE_INACTIVE_RACE));
}
} else {
b.append(TEXTTEMPLATE.textWithClass(linkText, STYLE_NAME_PREFIX + "InactiveRace"));
b.append(TEXTTEMPLATE.textWithClass(linkText, STYLE_INACTIVE_RACE));
}
}
}
@@ -354,26 +410,12 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
private SafeHtml getAnchor(String link, String linkText, String style) {
if (isEmbedded) {
return ANCHORTEMPLATE.anchorWithTarget(link, linkText, STYLE_NAME_PREFIX + style, "_blank");
return ANCHORTEMPLATE.anchorWithTarget(link, linkText, style, "_blank");
} else {
return ANCHORTEMPLATE.anchor(link, linkText, STYLE_NAME_PREFIX + style);
return ANCHORTEMPLATE.anchor(link, linkText, style);
}
}
private BreadcrumbPanel createBreadcrumbPanel() {
BreadcrumbPanel breadcrumbPanel = null;
if (root.equals("overview")) {
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = "/gwt/Spectator.html"
+ (showRaceDetails ? "?showRaceDetails=true" : "")
+ (debugParam != null && !debugParam.isEmpty() ? (showRaceDetails?"":"?")+"gwt.codesvr=" + debugParam : "");
ArrayList<Pair<String, String>> breadcrumbLinksData = new ArrayList<Pair<String, String>>();
breadcrumbLinksData.add(new Pair<String, String>(link, stringMessages.home()));
breadcrumbPanel = new BreadcrumbPanel(breadcrumbLinksData, leaderboardGroup.name);
}
return breadcrumbPanel;
}
@Override
public void setWelcomeWidgetVisible(boolean isVisible) {
if (welcomeWidget != null) {
@@ -15,11 +15,11 @@
</servlet-mapping>
<servlet>
<servlet-name>ModeratorApp</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.ModeratorApp</servlet-class>
<servlet-name>RegattaAndRaceDataJsonExportServlet</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.RegattaAndRaceDataJsonExportServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ModeratorApp</servlet-name>
<servlet-name>RegattaAndRaceDataJsonExportServlet</servlet-name>
<url-pattern>/moderator</url-pattern>
</servlet-mapping>
@@ -0,0 +1,16 @@
package com.sap.sailing.server.gateway.impl;
import javax.servlet.http.HttpServletResponse;
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
public abstract class JsonExportServlet extends SailingServerHttpServlet {
private static final long serialVersionUID = 7007196727805110847L;
protected void setJsonResponseHeader(HttpServletResponse resp) {
// to allow access to the json document directly from a client side javascript
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
}
}
@@ -22,19 +22,13 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
public class LeaderboardGroupJsonExportServlet extends SailingServerHttpServlet {
public class LeaderboardGroupJsonExportServlet extends JsonExportServlet {
private static final long serialVersionUID = 1351616646322956825L;
private static final String PARAM_NAME_LEADERBOARDGROUPNAME = "leaderboardGroupName";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// to allow access to the json document directly from a client side javascript
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
String leaderboardGroupName = req.getParameter(PARAM_NAME_LEADERBOARDGROUPNAME);
if (leaderboardGroupName == null) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Need to specify the name of a leaderboard group using the "+
@@ -145,6 +139,7 @@ public class LeaderboardGroupJsonExportServlet extends SailingServerHttpServlet
}
}
}
setJsonResponseHeader(resp);
jsonLeaderboardGroup.writeJSONString(resp.getWriter());
}
}
@@ -23,19 +23,13 @@ import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
public class LeaderboardJsonExportServlet extends SailingServerHttpServlet {
public class LeaderboardJsonExportServlet extends JsonExportServlet {
private static final long serialVersionUID = -2460691283231361152L;
private static final String PARAM_NAME_LEADERBOARDNAME = "leaderboardName";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// to allow access to the json document directly from a client side javascript
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
TimePoint timePoint = MillisecondsTimePoint.now();
String leaderboardName = req.getParameter(PARAM_NAME_LEADERBOARDNAME);
if (leaderboardName == null) {
@@ -111,6 +105,7 @@ public class LeaderboardJsonExportServlet extends SailingServerHttpServlet {
jsonEntry.put("isCorrected", leaderboard.getScoreCorrection().isScoreCorrected(competitor, raceColumn));
}
}
setJsonResponseHeader(resp);
jsonLeaderboard.writeJSONString(resp.getWriter());
} catch (NoWindException e) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
@@ -10,23 +10,18 @@ import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONArray;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
public class LeaderboardsJsonExportServlet extends SailingServerHttpServlet {
public class LeaderboardsJsonExportServlet extends JsonExportServlet {
private static final long serialVersionUID = -2193421590275280102L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// to allow access to the json document directly from a client side javascript
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
JSONArray jsonLeaderboards = new JSONArray();
Map<String, Leaderboard> leaderboards = getService().getLeaderboards();
for (String leaderboardName : leaderboards.keySet()) {
jsonLeaderboards.add(leaderboardName);
}
setJsonResponseHeader(resp);
jsonLeaderboards.writeJSONString(resp.getWriter());
}
@@ -34,11 +34,10 @@ 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.domain.tracking.Wind;
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
import com.sap.sailing.util.InvalidDateException;
public class ModeratorApp extends SailingServerHttpServlet {
private static final Logger logger = Logger.getLogger(ModeratorApp.class.getName());
public class RegattaAndRaceDataJsonExportServlet extends JsonExportServlet {
private static final Logger logger = Logger.getLogger(RegattaAndRaceDataJsonExportServlet.class.getName());
private static final long serialVersionUID = 1333207389294903999L;
@@ -77,7 +76,7 @@ public class ModeratorApp extends SailingServerHttpServlet {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unknown action \""+action+"\"");
}
} else {
resp.getWriter().println("Hello moderator!");
resp.getWriter().println("No action specified!");
}
} catch (Throwable e) {
resp.getWriter().println("Error processing request:");
@@ -140,6 +139,7 @@ public class ModeratorApp extends SailingServerHttpServlet {
jsonCompetitors.add(jsonCompetitor);
}
jsonRace.put("competitors", jsonCompetitors);
setJsonResponseHeader(resp);
jsonRace.writeJSONString(resp.getWriter());
} catch (InvalidDateException e) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
@@ -180,6 +180,7 @@ public class ModeratorApp extends SailingServerHttpServlet {
jsonWaypoint.put("buoys", jsonBuoys);
jsonWaypoints.add(jsonWaypoint);
}
setJsonResponseHeader(resp);
jsonWaypoints.writeJSONString(resp.getWriter());
} catch (InvalidDateException e) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
@@ -350,6 +351,7 @@ public class ModeratorApp extends SailingServerHttpServlet {
} catch (NoWindException e) {
// well, we don't know the wind direction... then no windward distance will be shown...
}
setJsonResponseHeader(resp);
jsonRace.writeJSONString(resp.getWriter());
} catch (InvalidDateException e) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Couldn't parse time specification " + e.getMessage());
@@ -411,6 +413,7 @@ public class ModeratorApp extends SailingServerHttpServlet {
jsonEvent.put("races", jsonRaces);
regattaList.add(jsonEvent);
}
setJsonResponseHeader(resp);
regattaList.writeJSONString(resp.getWriter());
}
}