Merge branch 'racecommittee_app' of ssh://sapsailing.com/home/trac/git into racecommittee_app

This commit is contained in:
Lukas Niemeier committed 2013-06-18 12:57:37 +02:00
commit ebfef7a808
21 files changed
+230 -54

No files matched your search

@@ -38,7 +38,6 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.CourseDataImpl;
import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
@@ -83,8 +82,8 @@ import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
@@ -330,26 +329,6 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
return resultDiscardingRule;
}
private CourseArea loadCourseAreaFromEvents(DBObject dbObject) {
Serializable courseAreaId = (Serializable) dbObject.get(FieldNames.COURSE_AREA_ID.name());
CourseArea result;
if (courseAreaId == null) {
result = null;
} else {
UUID courseAreaUuid = UUID.fromString(courseAreaId.toString());
Iterable<Event> allEvents = loadAllEvents();
result = null;
for (Event event : allEvents) {
for (CourseArea courseArea : event.getVenue().getCourseAreas()) {
if (courseArea.getId().equals(courseAreaUuid)) {
result = courseArea;
}
}
}
}
return result;
}
/**
* @return <code>null</code> if the regatta cannot be resolved; otherwise the leaderboard for the regatta specified
*/
@@ -379,7 +358,14 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
final ScoringScheme scoringScheme = loadScoringScheme(dbLeaderboard);
RaceLogStore raceLogStore = MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStore(
new MongoObjectFactoryImpl(database), this);
CourseArea courseArea = loadCourseAreaFromEvents(dbLeaderboard);
Serializable courseAreaId = (Serializable) dbLeaderboard.get(FieldNames.COURSE_AREA_ID.name());
CourseArea courseArea = null;
if (courseAreaId != null) {
UUID courseAreaUuid = UUID.fromString(courseAreaId.toString());
courseArea = DomainFactory.INSTANCE.getExistingCourseAreaById(courseAreaUuid);
}
result = new FlexibleLeaderboardImpl(raceLogStore, (String) dbLeaderboard.get(FieldNames.LEADERBOARD_NAME
.name()), scoreCorrection, resultDiscardingRule, scoringScheme, courseArea);
// For a FlexibleLeaderboard, fleets are owned by the leaderboard's RaceColumn objects. We need to manage
@@ -836,7 +822,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
private CourseArea loadCourseArea(DBObject courseAreaDBObject) {
String name = (String) courseAreaDBObject.get(FieldNames.COURSE_AREA_NAME.name());
Serializable id = (Serializable) courseAreaDBObject.get(FieldNames.COURSE_AREA_ID.name());
return new CourseAreaImpl(name, id);
return DomainFactory.INSTANCE.getOrCreateCourseArea(id, name);
}
@Override
@@ -878,7 +864,14 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
RaceLogStore raceLogStore = MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStore(
new MongoObjectFactoryImpl(database),
this);
CourseArea courseArea = loadCourseAreaFromEvents(dbRegatta);
Serializable courseAreaId = (Serializable) dbRegatta.get(FieldNames.COURSE_AREA_ID.name());
CourseArea courseArea = null;
if (courseAreaId != null) {
UUID courseAreaUuid = UUID.fromString(courseAreaId.toString());
courseArea = DomainFactory.INSTANCE.getExistingCourseAreaById(courseAreaUuid);
}
result = new RegattaImpl(raceLogStore, baseName, boatClass, series, /* persistent */ true, loadScoringScheme(dbRegatta), id, courseArea);
}
return result;
@@ -10,6 +10,6 @@ import com.sap.sailing.domain.common.WithID;
* @author Axel Uhl (D043530)
*
*/
public interface CourseArea extends Named, WithID {
public interface CourseArea extends Named, WithID, IsManagedBySharedDomainFactory {
}
@@ -77,6 +77,10 @@ public interface SharedDomainFactory {
Competitor createCompetitor(Serializable id, String name, Team team, Boat boat);
Competitor getOrCreateCompetitor(Serializable competitorId, String name, Team team, Boat boat);
CourseArea getOrCreateCourseArea(Serializable courseAreaId, String name);
CourseArea getExistingCourseAreaById(Serializable courseAreaId);
}
@@ -3,6 +3,8 @@ package com.sap.sailing.domain.base.impl;
import java.io.Serializable;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.IsManagedBySharedDomainFactory;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.common.impl.NamedImpl;
public class CourseAreaImpl extends NamedImpl implements CourseArea {
@@ -21,14 +23,7 @@ public class CourseAreaImpl extends NamedImpl implements CourseArea {
}
@Override
public boolean equals(Object obj) {
if (obj instanceof CourseArea) {
CourseArea courseArea = (CourseArea) obj;
if (this.id.equals(courseArea.getId())) {
return true;
}
return false;
}
return super.equals(obj);
public IsManagedBySharedDomainFactory resolve(SharedDomainFactory domainFactory) {
return domainFactory.getOrCreateCourseArea(id, getName());
}
}
@@ -22,6 +22,7 @@ import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.ControlPoint;
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.Gate;
@@ -88,6 +89,8 @@ public class DomainFactoryImpl implements DomainFactory {
private final Map<Serializable, Competitor> competitorCache;
private final Map<Serializable, CourseArea> courseAreaCache;
/**
* Weakly references the waypoints. If a waypoint is no longer strongly referenced, the corresponding reference contained
* as value will have its referred object be <code>null</code>. In this case, the methods reading from this cache will purge
@@ -134,6 +137,7 @@ public class DomainFactoryImpl implements DomainFactory {
competitorCache = new HashMap<Serializable, Competitor>();
waypointCache = new ConcurrentHashMap<Serializable, WeakWaypointReference>();
mayStartWithNoUpwindLeg = new HashSet<String>(Arrays.asList(new String[] { "extreme40", "ess", "ess40" }));
courseAreaCache = new HashMap<>();
}
@Override
@@ -452,4 +456,19 @@ public class DomainFactoryImpl implements DomainFactory {
return result;
}
@Override
public CourseArea getOrCreateCourseArea(Serializable courseAreaId, String name) {
CourseArea result = getExistingCourseAreaById(courseAreaId);
if (result == null) {
result = new CourseAreaImpl(name, courseAreaId);
courseAreaCache.put(courseAreaId, result);
}
return result;
}
@Override
public CourseArea getExistingCourseAreaById(Serializable courseAreaId) {
return courseAreaCache.get(courseAreaId);
}
}
@@ -2,6 +2,9 @@
<html>
<head>
<!--[if lt IE 9]>
<meta http-equiv="REFRESH" content="0; url=http://www.sapsailing.com/browser-info.html">
<![endif]-->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>SAP Sailing Analytics Leaderboard</title>
<meta content='width = device-width, initial-scale = 1.0, user-scalable = yes' name='viewport'>
@@ -2,6 +2,9 @@
<html>
<head>
<!--[if lt IE 9]>
<meta http-equiv="REFRESH" content="0; url=http://www.sapsailing.com/browser-info.html">
<![endif]-->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>SAP Sailing Analytics Race Board</title>
<meta content='width = device-width, initial-scale = 1.0, user-scalable = yes' name='viewport'>
@@ -7,6 +7,9 @@
<html>
<head>
<!--[if lt IE 9]>
<meta http-equiv="REFRESH" content="0; url=http://www.sapsailing.com/browser-info.html">
<![endif]-->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- <meta name="viewport" content="width=device-width" />-->
<meta content='width = device-width, initial-scale = 1.0, user-scalable = yes' name='viewport'>
@@ -2558,7 +2558,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
if (event != null) {
for (CourseArea courseArea : event.getVenue().getCourseAreas()) {
for (Leaderboard leaderboard : getService().getLeaderboards().values()) {
if (leaderboard.getDefaultCourseArea() != null && leaderboard.getDefaultCourseArea().equals(courseArea)) {
if (leaderboard.getDefaultCourseArea() != null && leaderboard.getDefaultCourseArea() == courseArea) {
RaceGroupDTO raceGroup = new RaceGroupDTO(leaderboard.getName());
raceGroup.courseAreaIdAsString = courseArea.getId().toString();
raceGroup.displayName = getRegattaNameFromLeaderboard(leaderboard);
@@ -35,7 +35,6 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CompetitorImpl;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
@@ -87,7 +86,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
final String[] courseAreaNames = new String[] { "Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrott" };
final Venue venue = new VenueImpl(venueName);
for (String courseAreaName : courseAreaNames) {
CourseArea courseArea = new CourseAreaImpl(courseAreaName, UUID.randomUUID());
CourseArea courseArea = DomainFactory.INSTANCE.getOrCreateCourseArea(UUID.randomUUID(), courseAreaName);
venue.addCourseArea(courseArea);
}
MongoObjectFactory mof = MongoFactory.INSTANCE.getMongoObjectFactory(getMongoService());
@@ -115,7 +114,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
final String publicationUrl = "http://myevent.sapsailing.com";
final String courseAreaName = "Alpha";
final Venue venue = new VenueImpl(venueName);
CourseArea courseArea = new CourseAreaImpl(courseAreaName, UUID.randomUUID());
CourseArea courseArea = DomainFactory.INSTANCE.getOrCreateCourseArea(UUID.randomUUID(), courseAreaName);
venue.addCourseArea(courseArea);
MongoObjectFactory mof = MongoFactory.INSTANCE.getMongoObjectFactory(getMongoService());
@@ -5,19 +5,25 @@ import java.io.Serializable;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
public class CourseAreaJsonDeserializer implements JsonDeserializer<CourseArea> {
public CourseArea deserialize(JSONObject object)
throws JsonDeserializationException {
String name = object.get(CourseAreaJsonSerializer.FIELD_NAME).toString();
Serializable id = (Serializable) object.get(CourseAreaJsonSerializer.FIELD_ID);
return new CourseAreaImpl(name, Helpers.tryUuidConversion(id));
}
private SharedDomainFactory factory;
public CourseAreaJsonDeserializer(SharedDomainFactory factory) {
this.factory = factory;
}
public CourseArea deserialize(JSONObject object)
throws JsonDeserializationException {
String name = object.get(CourseAreaJsonSerializer.FIELD_NAME).toString();
Serializable id = (Serializable) object.get(CourseAreaJsonSerializer.FIELD_ID);
return factory.getOrCreateCourseArea(Helpers.tryUuidConversion(id), name);
}
}
@@ -12,6 +12,8 @@ public class SeriesJsonSerializer implements JsonSerializer<Series> {
public static final String FIELD_NAME = "name";
public static final String FIELD_FLEETS = "fleets";
public static final String FIELD_RACES = "races";
public static final String FIELD_STARTS_WITH_ZERO_SCORE = "startsWithZeroScore";
public static final String FIELD_IS_MEDAL_SERIES = "isMedalSeries";
private final JsonSerializer<Fleet> fleetSerializer;
@@ -23,6 +25,8 @@ public class SeriesJsonSerializer implements JsonSerializer<Series> {
JSONObject result = new JSONObject();
result.put(FIELD_NAME, series.getName());
result.put(FIELD_IS_MEDAL_SERIES, series.isMedal());
result.put(FIELD_STARTS_WITH_ZERO_SCORE, series.isStartsWithZeroScore());
JSONArray fleetsJson = new JSONArray();
for (Fleet fleet : series.getFleets()) {
@@ -81,7 +81,7 @@ public class LeaderboardGroupJsonGetServlet extends AbstractJsonHttpServlet {
JSONObject jsonSeries = new JSONObject();
jsonSeries.put("name", series.getName());
jsonSeries.put("isMedalSeries", series.isMedal());
jsonSeries.put("startsWithZeroScore", series.isStartsWithZeroScore());
JSONArray jsonFleetsEntries = new JSONArray();
jsonSeries.put("fleets", jsonFleetsEntries);
for(Fleet fleet: series.getFleets()) {
@@ -42,7 +42,6 @@ import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaListener;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.Color;
@@ -69,8 +68,8 @@ import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoFactory;
@@ -265,10 +264,10 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
// This is more for debugging purposes than for anything else.
addFlexibleLeaderboard(LeaderboardNameConstants.DEFAULT_LEADERBOARD_NAME, null, new int[] { 5, 8 },
tractracDomainFactory.getBaseDomainFactory().createScoringScheme(ScoringSchemeType.LOW_POINT), null);
loadStoredEvents();
loadStoredRegattas();
loadRaceIDToRegattaAssociations();
loadStoredLeaderboardsAndGroups();
loadStoredEvents();
loadMediaLibary();
}
@@ -1806,7 +1805,7 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
@Override
public CourseArea addCourseArea(Serializable eventId, String courseAreaName, Serializable courseAreaId) {
CourseArea courseArea = new CourseAreaImpl(courseAreaName, courseAreaId);
CourseArea courseArea = com.sap.sailing.domain.base.DomainFactory.INSTANCE.getOrCreateCourseArea(courseAreaId, courseAreaName);
synchronized (eventsById) {
if (!eventsById.containsKey(eventId)) {
throw new IllegalArgumentException("No sailing event with ID " + eventId + " found.");
+81
View File
@@ -0,0 +1,81 @@
@import url(fontface.css);
body {
font-family: Arial, Verdana, sans-serif;
margin: 0;
padding: 0 0 50px 0;
background: #ebebec;
}
.LogoAndTitlePanel {
height: 68px;
font-family: Arial, Verdana, sans-serif;
position: fixed;
width: 100%;
top: 0;
background-image: url(images/white_gradient_header.png), url(images/header_bg_modern.png);
background-position: center top, 0 0;
background-repeat: no-repeat, repeat-x;
box-shadow: 0 0 20px #858585;
-moz-box-shadow: 0 0 20px #858585;
-webkit-box-shadow: 0 0 20px #858585;
}
h1, h2, h3, h4 {
font-weight: bold;
}
.LogoAndTitlePanel:after {
content:" ";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.RaceBoardHeaderPanel {
margin: 0 12px 14px 12px;
}
.sapLogo {
float: left;
margin: 13px 0 0 12px;
}
.sailingAnalyticsLabelPanel {
margin: 10px 0 0 0;
}
.sailingAnalyticsLabel {
float: left;
color: #fff;
font-size: 14px;
font-weight: bold;
margin: 15px 0 0 0;
}
a {
color: #A1A1A1;
text-decoration: none;
}
a:hover {
text-decoration: none;
}
.error-code {
font-size: 48px;
color: #f0ab00;
margin: 20px 0 15px 0;
}
.error-message {
font-size: 30px;
color: #f0ab00;
margin: 0 0 15px 0;
font-weight: normal;
}
#content {
margin: 100px auto 0;
width: 600px;
text-align: center;
}
.follow-text {
color: #666;
}
.follow-text ul {
list-style: none;
margin: 0;
padding: 0;
}
.follow-text ul li {
margin: 0 0 10px 0;
}
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SAP Sailing Analytics Suite - Unsupported Browser!</title>
<meta http-equiv="content-type"
content="text/html; charset=UTF-8" />
<meta http-equiv="content-style-type" content="text/css" />
<link rel="shortcut icon" type="image/x-icon" href="/sap.ico" />
<link href="browser-info.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="LogoAndTitlePanel">
<a class="gwt-Anchor sapLogo" href="http://www.sap.com">
<img class="linkNoBorder" src="images/sap_66_transparent.png" alt="SAP Website"/>
</a>
<div class="sailingAnalyticsLabelPanel">
<div class="gwt-Label sailingAnalyticsLabel boldLabel">Sailing Analytics</div>
</div>
</div>
<div id="content">
<img src="images/404errorPageIcon.png" alt="Error Page Icon">
<h2 class="error-code">Unsupported Browser!</h2>
<h3 class="error-message">You are using an unsupported Version of the Internet Explorer.
<span style="font-weight:bold">Please use the Internet Explorer 9 or higher!</span>
</h3>
<div class="follow-text">
<p>You can also use one of the following supported Web Browser:</p>
<ul>
<li>
<a href="http://www.mozilla.org">Mozilla Firefox</a>
</li>
<li>
<a href="http://www.apple.com/safari">Apple Safari</a>
</li>
<li>
<a href="http://www.google.com/chrome">Google Chrome</a>
</li>
</ul>
</div>
</div>
</body>
</html>
+3 -1
View File
@@ -7,4 +7,6 @@ bin.includes = META-INF/,\
webfonts/,\
fontface.css,\
SAP.html,\
STG.html
STG.html,\
browser-info.html,\
browser-info.css
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -86,8 +86,9 @@ public class OnlineDataManager extends DataManager {
}
protected void reloadEvents(LoadClient<Collection<EventBase>> client) {
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
DataParser<Collection<EventBase>> parser = new EventsDataParser(new EventBaseJsonDeserializer(
new VenueJsonDeserializer(new CourseAreaJsonDeserializer())));
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(domainFactory))));
DataHandler<Collection<EventBase>> handler = new EventsDataHandler(this, client);
try {
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.ControlPoint;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Gate;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.Nationality;
@@ -21,6 +22,7 @@ import com.sap.sailing.domain.base.Team;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.BoatClassImpl;
import com.sap.sailing.domain.base.impl.CompetitorImpl;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.GateImpl;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.NationalityImpl;
@@ -38,6 +40,7 @@ public enum DomainFactoryImpl implements SharedDomainFactory {
private final ConcurrentHashMap<Serializable, Waypoint> waypointCache = new ConcurrentHashMap<Serializable, Waypoint>();
private final Set<String> mayStartWithNoUpwindLeg = new HashSet<String>(Arrays.asList(new String[] { "extreme40", "ess", "ess40" }));
private final Map<Serializable, Competitor> competitorCache = new HashMap<Serializable, Competitor>();
private final Map<Serializable, CourseArea> courseAreaCache = new HashMap<Serializable, CourseArea>();
public Nationality getOrCreateNationality(String threeLetterIOCCode) {
synchronized (nationalityCache) {
@@ -149,4 +152,19 @@ public enum DomainFactoryImpl implements SharedDomainFactory {
return result;
}
@Override
public CourseArea getOrCreateCourseArea(Serializable courseAreaId, String name) {
CourseArea result = getExistingCourseAreaById(courseAreaId);
if (result == null) {
result = new CourseAreaImpl(name, courseAreaId);
courseAreaCache.put(courseAreaId, result);
}
return result;
}
@Override
public CourseArea getExistingCourseAreaById(Serializable courseAreaId) {
return courseAreaCache.get(courseAreaId);
}
}