Merge branch 'origin/master'

This commit is contained in:
Christopher Ronnewinkel (D036654) committed 2014-05-13 17:13:18 +02:00
commit f3f60c4ef6
662 files changed
+105350 -14232

No files matched your search

+9
View File
@@ -241,6 +241,15 @@ if [[ "$@" == "release" ]]; then
if [[ $OSGI_BUNDLE_NAME != "" ]]; then
SIMPLE_VERSION_INFO="$OSGI_BUNDLE_NAME-$HEAD_DATE"
fi
echo "
MONGODB_NAME=myspecificevent
REPLICATION_CHANNEL=myspecificevent
SERVER_STARTUP_NOTIFY=simon.marcel.pamies@sap.com
SERVER_NAME=LIVE
USE_ENVIRONMENT=live-server
INSTALL_FROM_RELEASE=$SIMPLE_VERSION_INFO
" >> $ACDIR/amazon-launch-config.txt
mkdir $PROJECT_HOME/dist/$SIMPLE_VERSION_INFO
`which tar` cvzf $PROJECT_HOME/dist/$SIMPLE_VERSION_INFO/$SIMPLE_VERSION_INFO.tar.gz *
+16
View File
@@ -0,0 +1,16 @@
DEPLOY_TO=server
SERVER_NAME=LIVE
MEMORY=4096m
REPLICATION_HOST=172.31.25.253
REPLICATION_CHANNEL=sapsailinganalytics-live
TELNET_PORT=14888
SERVER_PORT=8888
MONGODB_HOST=172.31.25.253
MONGODB_PORT=10201
EXPEDITION_PORT=2010
REPLICATE_ON_START=False
REPLICATE_MASTER_SERVLET_HOST=
REPLICATE_MASTER_SERVLET_PORT=
REPLICATE_MASTER_QUEUE_HOST=
REPLICATE_MASTER_QUEUE_PORT=
ADDITIONAL_JAVA_ARGS="-XX:+UseMembar -XX:+UseParallelGC -XX:+UseParallelOldGC -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dorg.eclipse.jetty.LEVEL=OFF -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog"
+60
View File
@@ -0,0 +1,60 @@
#!/bin/bash
#
# sailing Starts sailing services
#
# chkconfig: 2345 95 10
# description: Sailing contains all sailing services
# Source function library.
. /etc/init.d/functions
RETVAL=0
JAVA_START_INSTANCES="server"
GIT_REPOSITORY=/home/sailing/code
start_tmux() {
su - sailing -c "/home/sailing/bin/tmuxConsole.sh unattended"
success
}
start_servers() {
for conf in $JAVA_START_INSTANCES; do
echo "Checking for amazon update..."
su - sailing -c "cd /home/sailing/servers/$conf && $GIT_REPOSITORY/java/target/refreshInstance.sh auto-install" 2>/var/log/sailing.err >/var/log/sailing.out
echo "Starting Java server $conf"
su - sailing -c "cd /home/sailing/servers/$conf && ./start" 2>/var/log/sailing.err >/var/log/sailing.out
RETVAL=$?
[ $RETVAL -eq 0 ] && success || failure
done
}
stop_servers() {
for conf in $JAVA_START_INSTANCES; do
echo "Stopping Java server $conf"
su - sailing -c "cd /home/sailing/servers/$conf && ./stop"
RETVAL=$?
[ $RETVAL -eq 0 ] && success || failure
done
}
# See how we were called.
case "$1" in
start)
start_servers
;;
stop)
stop_servers
;;
status)
status java
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|status|stop}"
RETVAL=3
esac
exit $RETVAL
+1 -1
View File
@@ -34,7 +34,7 @@ Like businesses, sailors need the latest information to make strategic decisions
* [[Architecture and Infrastructure|wiki/architecture-and-infrastructure]]
* [[Sailing Domain Algorithms|wiki/sailing-domain-algorithms]]
* [[Inventory|wiki/inventar-liste]]
* [[Smartphone Tracking|wiki/smartphone-tracking]]
* [[RaceLog tracking|wiki/racelog-tracking]]
* [[Racecommittee App|wiki/racecommittee-app]]
* [[Web Services API|wiki/sailing-webservices]]
* [[Theses (Bachelor, Master, ...)|wiki/theses]]
@@ -14,5 +14,8 @@ Export-Package: com.sap.sailing.domain.common,
com.sap.sailing.domain.common.quadtree,
com.sap.sailing.domain.common.quadtree.impl;x-friends:="com.sap.sailing.domain.test",
com.sap.sailing.domain.common.racelog,
com.sap.sailing.domain.common.racelog.tracking,
com.sap.sailing.domain.common.racelog.utils,
com.sap.sailing.domain.common.scalablevalue,
com.sap.sailing.domain.common.scalablevalue.impl,
com.sap.sailing.domain.common.trackfiles
@@ -6,4 +6,7 @@
<source path='common/racelog'/>
<source path='common/filter'/>
<source path='common/media'/>
<source path='common/scalablevalue'/>
<source path='common/racelog/tracking'/>
<source path='common/scalablevalue/impl'/>
</module>
@@ -17,9 +17,10 @@ public enum DetailType implements Serializable {
ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1, ASCENDING), VELOCITY_MADE_GOOD_IN_KNOTS(2, DESCENDING),
GAP_TO_LEADER_IN_SECONDS(0, ASCENDING), GAP_CHANGE_SINCE_LEG_START_IN_SECONDS(0, ASCENDING),
SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED(0, ASCENDING), WINDWARD_DISTANCE_TO_GO_IN_METERS(0, ASCENDING),
AVERAGE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), RACE_DISTANCE_TRAVELED(0, ASCENDING),
AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), RACE_DISTANCE_TRAVELED(0, ASCENDING),
RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_GAP_TO_LEADER_IN_SECONDS(0, ASCENDING),
RACE_DISTANCE_TO_LEADER_IN_METERS(0, ASCENDING), RACE_AVERAGE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING),
RACE_DISTANCE_TO_LEADER_IN_METERS(0, ASCENDING), RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING),
RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING),
WINDWARD_DISTANCE_TO_OVERALL_LEADER(0, ASCENDING), START_TACK(0, ASCENDING), DISTANCE_TO_START_AT_RACE_START(1, ASCENDING),
SPEED_OVER_GROUND_AT_RACE_START(1, DESCENDING), SPEED_OVER_GROUND_WHEN_PASSING_START(1, DESCENDING),
DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS(1, ASCENDING),
@@ -0,0 +1,20 @@
package com.sap.sailing.domain.common;
public class DoublePair {
private final double a;
private final double b;
public DoublePair(double a, double b) {
super();
this.a = a;
this.b = b;
}
public double getA() {
return a;
}
public double getB() {
return b;
}
}
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.common.impl.MillisecondsDurationImpl;
*/
public interface Duration extends Serializable, Comparable<Duration> {
static final Duration NULL = new MillisecondsDurationImpl(0);
static final Duration ONE_SECOND = new MillisecondsDurationImpl(1000);
static final Duration ONE_MINUTE = ONE_SECOND.times(60);
static final Duration ONE_HOUR = ONE_MINUTE.times(60);
@@ -12,13 +12,13 @@ package com.sap.sailing.domain.common;
*/
public enum PassingInstruction {
None,
Port,
Starboard,
Gate,
Line,
Offset,
FixedBearing;
None(1, 2),
Port(1),
Starboard(1),
Gate(2),
Line(2),
Offset(2),
FixedBearing(1);
public static PassingInstruction[] relevantValues() {
PassingInstruction[] uiValues = new PassingInstruction[PassingInstruction.values().length - 1];
@@ -40,4 +40,15 @@ public enum PassingInstruction {
return null;
}
/**
* Denotes for which types of {@code ControlPoints} (defined by the number of marks they are made up of)
* this passing instruction is applicable.<p>
* E.g. {@code [1,2]} denotes that the passing instruction is applicable for {@code ControlPoints} with either one
* or two marks.
*/
public final int[] applicability;
private PassingInstruction(int... applicability) {
this.applicability = applicability;
}
}
@@ -1,6 +1,6 @@
package com.sap.sailing.domain.common;
public enum ScoringSchemeType {
LOW_POINT, HIGH_POINT, HIGH_POINT_ESS_OVERALL, HIGH_POINT_LAST_BREAKS_TIE,
HIGH_POINT_FIRST_GETS_TEN, HIGH_POINT_FIRST_GETS_ONE, LOW_POINT_WINNER_GETS_ZERO
LOW_POINT, HIGH_POINT, HIGH_POINT_ESS_OVERALL, HIGH_POINT_LAST_BREAKS_TIE, HIGH_POINT_FIRST_GETS_TEN,
HIGH_POINT_FIRST_GETS_ONE, LOW_POINT_WINNER_GETS_ZERO, HIGH_POINT_WINNER_GETS_SIX
}
@@ -0,0 +1,67 @@
package com.sap.sailing.domain.common;
import java.io.Serializable;
public interface TimeRange extends Comparable<TimeRange>, Serializable {
/**
* @return {@code null}, if the timepoint is at the beginning of time
*/
TimePoint from();
/**
* @return {@code null}, if the timepoint is at the beginning of time
*/
TimePoint to();
/**
* Also returns true if (either or both) the from or to timepoints are equal.
* E.g. 10-100 lies within 10-00, and 10-50 lies within 10-100.
* @param other
* @return
*/
boolean liesWithin(TimeRange other);
/**
* Reverse operation of {@link #liesWithin(TimeRange)}.
* x.includes(y) = y.liesWithin(x)
* @param other
* @return
*/
boolean includes(TimeRange other);
boolean includes(TimePoint timePoint);
boolean intersects(TimeRange other);
boolean startsBefore(TimeRange other);
boolean endsAfter(TimeRange other);
/**
* Is the time range open ended towards older timepoints?
*/
boolean openBeginning();
/**
* Is the time range open ended towards newer timepoints?
*/
boolean openEnd();
/**
* Get time-difference between the timepoint and this timerange.
* It will be 0 if the timepoint lies within the timerange, otherwise the time-difference
* to either the start or end of the timerange, depending on which is closer. The
* time difference is a duration that is guaranteed to be positive.
*/
Duration timeDifference(TimePoint timePoint);
/**
* Merges the two ranges, only possible if {@code other} {@link #intersects()} this range.
*/
TimeRange union(TimeRange other);
/**
* Intersection of the two ranges, only possible if {@code other} {@link #intersects()} this range.
*/
TimeRange intersection(TimeRange other);
}
@@ -30,7 +30,7 @@ public abstract class AbstractLeaderboardDTO implements Serializable {
public UUID defaultCourseAreaId;
public String defaultCourseAreaName;
public ScoringSchemeType scoringScheme;
public LeaderboardType type;
public LeaderboardType type;
private Long delayToLiveInMillisForLatestRace;
@@ -23,7 +23,7 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial
private String idAsString;
private BoatClassDTO boatClass;
CompetitorDTOImpl() {}
public CompetitorDTOImpl() {}
public CompetitorDTOImpl(String name, Color color, String twoLetterIsoCountryCode, String threeLetterIocCountryCode,
String countryName, String sailID, String idAsString, BoatClassDTO boatClass) {
@@ -44,7 +44,9 @@ public class LeaderboardEntryDTO implements Serializable {
public Double windwardDistanceToOverallLeaderInMeters;
public Double averageCrossTrackErrorInMeters;
public Double averageAbsoluteCrossTrackErrorInMeters;
public Double averageSignedCrossTrackErrorInMeters;
public Double distanceToStartLineFiveSecondsBeforeStartInMeters;
@@ -99,7 +101,9 @@ public class LeaderboardEntryDTO implements Serializable {
final int prime = 31;
int result = 1;
result = prime * result
+ ((averageCrossTrackErrorInMeters == null) ? 0 : averageCrossTrackErrorInMeters.hashCode());
+ ((averageAbsoluteCrossTrackErrorInMeters == null) ? 0 : averageAbsoluteCrossTrackErrorInMeters.hashCode());
result = prime * result
+ ((averageSignedCrossTrackErrorInMeters == null) ? 0 : averageSignedCrossTrackErrorInMeters.hashCode());
result = prime * result + (discarded ? 1231 : 1237);
result = prime
* result
@@ -141,10 +145,15 @@ public class LeaderboardEntryDTO implements Serializable {
if (getClass() != obj.getClass())
return false;
LeaderboardEntryDTO other = (LeaderboardEntryDTO) obj;
if (averageCrossTrackErrorInMeters == null) {
if (other.averageCrossTrackErrorInMeters != null)
if (averageAbsoluteCrossTrackErrorInMeters == null) {
if (other.averageAbsoluteCrossTrackErrorInMeters != null)
return false;
} else if (!averageCrossTrackErrorInMeters.equals(other.averageCrossTrackErrorInMeters))
} else if (!averageAbsoluteCrossTrackErrorInMeters.equals(other.averageAbsoluteCrossTrackErrorInMeters))
return false;
if (averageSignedCrossTrackErrorInMeters == null) {
if (other.averageSignedCrossTrackErrorInMeters != null)
return false;
} else if (!averageSignedCrossTrackErrorInMeters.equals(other.averageSignedCrossTrackErrorInMeters))
return false;
if (discarded != other.discarded)
return false;
@@ -46,13 +46,16 @@ public class LegEntryDTO implements Serializable {
public boolean finished;
public Map<ManeuverType, Integer> numberOfManeuvers;
public Map<ManeuverType, Double> averageManeuverLossInMeters;
public Double averageCrossTrackErrorInMeters;
public Double averageAbsoluteCrossTrackErrorInMeters;
public Double averageSignedCrossTrackErrorInMeters;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((averageCrossTrackErrorInMeters == null) ? 0 : averageCrossTrackErrorInMeters.hashCode());
+ ((averageAbsoluteCrossTrackErrorInMeters == null) ? 0 : averageAbsoluteCrossTrackErrorInMeters.hashCode());
result = prime * result
+ ((averageSignedCrossTrackErrorInMeters == null) ? 0 : averageSignedCrossTrackErrorInMeters.hashCode());
result = prime * result + ((averageManeuverLossInMeters == null) ? 0 : averageManeuverLossInMeters.hashCode());
result = prime * result
+ ((averageSpeedOverGroundInKnots == null) ? 0 : averageSpeedOverGroundInKnots.hashCode());
@@ -87,10 +90,15 @@ public class LegEntryDTO implements Serializable {
if (getClass() != obj.getClass())
return false;
LegEntryDTO other = (LegEntryDTO) obj;
if (averageCrossTrackErrorInMeters == null) {
if (other.averageCrossTrackErrorInMeters != null)
if (averageAbsoluteCrossTrackErrorInMeters == null) {
if (other.averageAbsoluteCrossTrackErrorInMeters != null)
return false;
} else if (!averageCrossTrackErrorInMeters.equals(other.averageCrossTrackErrorInMeters))
} else if (!averageAbsoluteCrossTrackErrorInMeters.equals(other.averageAbsoluteCrossTrackErrorInMeters))
return false;
if (averageSignedCrossTrackErrorInMeters == null) {
if (other.averageSignedCrossTrackErrorInMeters != null)
return false;
} else if (!averageSignedCrossTrackErrorInMeters.equals(other.averageSignedCrossTrackErrorInMeters))
return false;
if (averageManeuverLossInMeters == null) {
if (other.averageManeuverLossInMeters != null)
@@ -22,6 +22,8 @@ public class RaceColumnDTO extends NamedDTO implements Serializable {
private Boolean isValidInTotalScore;
private Double explicitFactor;
private double effectiveFactor;
private Map<FleetDTO, RaceLogTrackingInfoDTO> raceLogTrackingInfos = new HashMap<FleetDTO, RaceLogTrackingInfoDTO>();
RaceColumnDTO() {} // for GWT serialization
@@ -283,4 +285,12 @@ public class RaceColumnDTO extends NamedDTO implements Serializable {
public double getEffectiveFactor() {
return effectiveFactor;
}
public RaceLogTrackingInfoDTO getRaceLogTrackingInfo(FleetDTO fleet) {
return raceLogTrackingInfos.get(fleet);
}
public void setRaceLogTrackingInfo(FleetDTO fleet, RaceLogTrackingInfoDTO info) {
raceLogTrackingInfos.put(fleet, info);
}
}
@@ -0,0 +1,21 @@
package com.sap.sailing.domain.common.dto;
import java.io.Serializable;
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
public class RaceLogTrackingInfoDTO implements Serializable {
private static final long serialVersionUID = -6861382173074620168L;
public boolean raceLogTrackerExists;
public boolean competitorRegistrationsExists;
public RaceLogTrackingState raceLogTrackingState;
protected RaceLogTrackingInfoDTO() {}
public RaceLogTrackingInfoDTO(boolean raceLogTrackerExists, boolean competitorRegistrationsExists,
RaceLogTrackingState raceLogTrackingState) {
this.raceLogTrackerExists = raceLogTrackerExists;
this.competitorRegistrationsExists = competitorRegistrationsExists;
this.raceLogTrackingState = raceLogTrackingState;
}
}
@@ -1,112 +1,113 @@
package com.sap.sailing.domain.common.impl;
import java.util.Comparator;
import java.util.Date;
import com.sap.sailing.domain.common.Duration;
import com.sap.sailing.domain.common.TimePoint;
public abstract class AbstractTimePoint implements TimePoint {
private static final long serialVersionUID = 8825508619301420378L;
public static Comparator<TimePoint> TIMEPOINT_COMPARATOR = new SerializableComparator<TimePoint>() {
private static final long serialVersionUID = 7644726881387366025L;
@Override
public int compare(TimePoint o1, TimePoint o2) {
long milliDiff = o1.asMillis() - o2.asMillis();
return milliDiff<0 ? -1 : milliDiff == 0 ? 0 : 1;
}
};
@Override
public int compareTo(TimePoint o) {
return TIMEPOINT_COMPARATOR.compare(this, o);
}
@Override
public Date asDate() {
Date result = getDateFromCache();
if (result == null) {
result = new Date(asMillis());
cacheDate(result);
}
return result;
}
@Override
public TimePoint plus(Duration duration) {
final TimePoint result;
if (duration != null) {
result = plus(duration.asMillis());
} else {
result = this;
}
return result;
}
@Override
public TimePoint minus(Duration duration) {
final TimePoint result;
if (duration != null) {
result = minus(duration.asMillis());
} else {
result = this;
}
return result;
}
@Override
public Duration until(TimePoint later) {
return new MillisecondsDurationImpl(later.asMillis()-asMillis());
}
@Override
public TimePoint plus(long milliseconds) {
return new MillisecondsTimePoint(asMillis()+milliseconds);
}
@Override
public TimePoint minus(long milliseconds) {
return plus(-milliseconds);
}
@Override
public boolean after(TimePoint other) {
return this.compareTo(other) > 0;
}
@Override
public boolean before(TimePoint other) {
return this.compareTo(other) < 0;
}
@Override
public int hashCode() {
return (int) (asMillis() & Integer.MAX_VALUE);
}
@Override
public boolean equals(Object obj) {
return compareTo((TimePoint) obj) == 0;
}
@Override
public String toString() {
return asDate().toString();
}
/**
* A subclass may implement a cache for the {@link Date} representation by overriding this method as well
* as {@link #cacheDate(Date)}.
*/
protected Date getDateFromCache() {
return null;
}
/**
* A subclass may implement a cache for the {@link Date} representation by overriding this method as well
* as {@link #getDate()}.
*/
protected void cacheDate(Date date) {}
}
package com.sap.sailing.domain.common.impl;
import java.util.Comparator;
import java.util.Date;
import com.sap.sailing.domain.common.Duration;
import com.sap.sailing.domain.common.TimePoint;
public abstract class AbstractTimePoint implements TimePoint {
private static final long serialVersionUID = 8825508619301420378L;
public static Comparator<TimePoint> TIMEPOINT_COMPARATOR = new SerializableComparator<TimePoint>() {
private static final long serialVersionUID = 7644726881387366025L;
@Override
public int compare(TimePoint o1, TimePoint o2) {
long o1Millis = o1.asMillis();
long o2Millis = o2.asMillis();
return o1Millis<o2Millis?-1:o1Millis==o2Millis?0:1;
}
};
@Override
public int compareTo(TimePoint o) {
return TIMEPOINT_COMPARATOR.compare(this, o);
}
@Override
public Date asDate() {
Date result = getDateFromCache();
if (result == null) {
result = new Date(asMillis());
cacheDate(result);
}
return result;
}
@Override
public TimePoint plus(Duration duration) {
final TimePoint result;
if (duration != null) {
result = plus(duration.asMillis());
} else {
result = this;
}
return result;
}
@Override
public TimePoint minus(Duration duration) {
final TimePoint result;
if (duration != null) {
result = minus(duration.asMillis());
} else {
result = this;
}
return result;
}
@Override
public Duration until(TimePoint later) {
return new MillisecondsDurationImpl(later.asMillis()-asMillis());
}
@Override
public TimePoint plus(long milliseconds) {
return new MillisecondsTimePoint(asMillis()+milliseconds);
}
@Override
public TimePoint minus(long milliseconds) {
return plus(-milliseconds);
}
@Override
public boolean after(TimePoint other) {
return this.compareTo(other) > 0;
}
@Override
public boolean before(TimePoint other) {
return this.compareTo(other) < 0;
}
@Override
public int hashCode() {
return (int) (asMillis() & Integer.MAX_VALUE);
}
@Override
public boolean equals(Object obj) {
return compareTo((TimePoint) obj) == 0;
}
@Override
public String toString() {
return asDate().toString();
}
/**
* A subclass may implement a cache for the {@link Date} representation by overriding this method as well
* as {@link #cacheDate(Date)}.
*/
protected Date getDateFromCache() {
return null;
}
/**
* A subclass may implement a cache for the {@link Date} representation by overriding this method as well
* as {@link #getDate()}.
*/
protected void cacheDate(Date date) {}
}
@@ -0,0 +1,121 @@
package com.sap.sailing.domain.common.impl;
import com.sap.sailing.domain.common.Duration;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.TimeRange;
import com.sap.sailing.domain.common.impl.Util.Pair;
public class TimeRangeImpl extends Pair<TimePoint, TimePoint> implements TimeRange {
public static final TimePoint BeginningOfTime = new MillisecondsTimePoint(Long.MIN_VALUE);
public static final TimePoint EndOfTime = new MillisecondsTimePoint(Long.MAX_VALUE);
private static final long serialVersionUID = 8710198176227507300L;
public static TimeRange create(long fromMillis, long toMillis) {
return new TimeRangeImpl(new MillisecondsTimePoint(fromMillis), new MillisecondsTimePoint(toMillis));
}
public TimeRangeImpl(TimePoint from, TimePoint to) {
super(from == null ? BeginningOfTime : from, to == null ? EndOfTime : to);
if (from().after(to())) throw new IllegalArgumentException(String.format("from (%s) must lie before to (%s) in a TimeRange", from(), to()));
}
@Override
public int compareTo(TimeRange other) {
if (other.from().equals(from()) && other.to().equals(to())) return 0;
return startsBefore(other) ? -1 : 1;
}
@Override
public TimePoint from() {
return getA();
}
@Override
public TimePoint to() {
return getB();
}
@Override
public boolean liesWithin(TimeRange other) {
return from().compareTo(other.from()) >= 0 && to().compareTo(other.to()) <= 0;
}
@Override
public boolean includes(TimeRange other) {
return other.liesWithin(this);
}
@Override
public boolean intersects(TimeRange other) {
return includes(other.from()) || includes(other.to()) || liesWithin(other);
}
@Override
public boolean includes(TimePoint timePoint) {
return from().compareTo(timePoint) <= 0 && to().compareTo(timePoint) >= 0;
}
@Override
public boolean startsBefore(TimeRange other) {
return from().before(other.from());
}
@Override
public boolean endsAfter(TimeRange other) {
return to().after(other.to());
}
@Override
public Duration timeDifference(TimePoint timePoint) {
final Duration result;
if (includes(timePoint)) {
result = Duration.NULL;
} else if (timePoint.before(from())) {
result = timePoint.until(from());
} else {
result = to().until(timePoint);
}
return result;
}
@Override
public TimeRange union(TimeRange other) {
if (! intersects(other)) return null;
TimePoint newFrom = startsBefore(other) ? from() : other.from();
TimePoint newTo = endsAfter(other) ? to() : other.to();
return new TimeRangeImpl(newFrom, newTo);
}
@Override
public boolean openBeginning() {
return from().equals(BeginningOfTime);
}
@Override
public boolean openEnd() {
return to().equals(EndOfTime);
}
@Override
public TimeRange intersection(TimeRange other) {
if (! intersects(other)) return null;
TimePoint newFrom = startsBefore(other) ? other.from() : from();
TimePoint newTo = endsAfter(other) ? other.to() : to();
return new TimeRangeImpl(newFrom, newTo);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof TimeRange) {
TimeRange other = (TimeRange) obj;
return from().equals(other.from()) && to().equals(other.to());
}
return super.equals(obj);
}
@Override
public String toString() {
return from() + "-" + to();
}
}
@@ -0,0 +1,24 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class NoCorrespondingServiceRegisteredException extends RuntimeException {
public String type;
public String serviceInterface;
private static final long serialVersionUID = -358955216089477585L;
protected NoCorrespondingServiceRegisteredException() {}
public NoCorrespondingServiceRegisteredException(String message, String type, String serviceInterface) {
super(message);
this.type = type;
this.serviceInterface = serviceInterface;
}
public String getDeviceType() {
return type;
}
@Override
public String toString() {
return super.toString() + " (Service: " + serviceInterface + ", Type: " + type + ")";
}
}
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class NotDenotableForRaceLogTrackingException extends Exception {
private static final long serialVersionUID = 6721038282862173471L;
public NotDenotableForRaceLogTrackingException() {
super();
}
public NotDenotableForRaceLogTrackingException(String msg) {
super(msg);
}
}
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class NotDenotedForRaceLogTrackingException extends Exception {
private static final long serialVersionUID = 6721038282862173471L;
public NotDenotedForRaceLogTrackingException() {
super();
}
public NotDenotedForRaceLogTrackingException(String msg) {
super(msg);
}
}
@@ -0,0 +1,13 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class NotRevokableException extends Exception {
private static final long serialVersionUID = 6825451915706047105L;
public NotRevokableException() {
super();
}
public NotRevokableException(String msg) {
super(msg);
}
}
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class RaceLogRaceTrackerExistsException extends RuntimeException {
private static final long serialVersionUID = 6721038282862173471L;
public RaceLogRaceTrackerExistsException() {
super();
}
public RaceLogRaceTrackerExistsException(String raceLogName) {
super("Tracker for racelog " + raceLogName + " already exists");
}
}
@@ -0,0 +1,30 @@
package com.sap.sailing.domain.common.racelog.tracking;
/**
* The state of the race tracked via the racelog. This can be determined by inspecting the corresponding events
* in the racelog with the {@link RaceLogTrackingStateAnalyzer}.
* @author Fredrik Teschke
*
*/
public enum RaceLogTrackingState {
//can't determine whether tracking has ended from race log, therefore omitting TRACKING_ENDED state for now
/**
* no {@link DenoteForTrackingEvent} is present
*/
NOT_A_RACELOG_TRACKED_RACE,
/**
* a {@link DenoteForTrackingEvent} is present, but no {@link StartTrackingEvent} yet.
*/
AWAITING_RACE_DEFINITION,
/**
* a {@link StartTrackingEvent} is present
*/
TRACKING;
public boolean isForTracking() {
return this != NOT_A_RACELOG_TRACKED_RACE;
}
}
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class RaceNotCreatedException extends RuntimeException {
private static final long serialVersionUID = 6721038282862173471L;
public RaceNotCreatedException() {
super();
}
public RaceNotCreatedException(String msg) {
super(msg);
}
}
@@ -0,0 +1,37 @@
package com.sap.sailing.domain.common.racelog.tracking;
/**
* Only can provide the service for a single {@code type}, e.g. on smartphones with no OSGi context.
* Optionally, a {@link #setFallbackService(Object) fallback} can be set.
* @author Fredrik Teschke
*/
public class SingleTypeBasedServiceFinderImpl<ServiceType> implements
TypeBasedServiceFinder<ServiceType> {
private final ServiceType service;
private final String type;
private ServiceType fallback;
public SingleTypeBasedServiceFinderImpl(ServiceType service, ServiceType fallback, String type) {
this.service = service;
this.type = type;
this.fallback = fallback;
}
public SingleTypeBasedServiceFinderImpl(ServiceType service, String type) {
this(service, null, type);
}
@Override
public ServiceType findService(String type)
throws NoCorrespondingServiceRegisteredException {
if (type.equals(this.type)) return service;
if (fallback != null) return fallback;
throw new NoCorrespondingServiceRegisteredException("Only one service registered", type, service.getClass().getSimpleName());
}
@Override
public void setFallbackService(ServiceType fallback) {
this.fallback = fallback;
}
}
@@ -0,0 +1,30 @@
package com.sap.sailing.domain.common.racelog.tracking;
import java.io.IOException;
public class TransformationException extends IOException {
private static final long serialVersionUID = -7795777645371428971L;
public TransformationException() {
}
public TransformationException(Class<?> from, Class<?> to, String at, Throwable e) {
super("Couldn't transform "+from.getName()+" into "+to.getName()+" at "+at, e);
}
public TransformationException(Class<?> from, Class<?> to, String at) {
this(from, to, at, null);
}
public TransformationException(String message, Throwable e) {
super(message, e);
}
public TransformationException(Throwable e) {
super(e);
}
public TransformationException(String message) {
super(message);
}
}
@@ -0,0 +1,13 @@
package com.sap.sailing.domain.common.racelog.tracking;
/**
* Handle transformation between two types. Most likely use-case is serialization,
* e.g. for JSON documents or database persistence.
*
* @author Fredrik Teschke
*
*/
public interface TransformationHandler<T1, T2> {
T1 transformBack(T2 object) throws TransformationException;
T2 transformForth(T1 object) throws TransformationException;
}
@@ -0,0 +1,29 @@
package com.sap.sailing.domain.common.racelog.tracking;
/**
* @author Fredrik Teschke
*
* @param <ServiceType> Specifies desired the service interface
*/
public interface TypeBasedServiceFinder<ServiceType> {
public static final String TYPE = "type";
/**
* Find a service that implements the <ServiceType> interface for the specified {@code type}
* of object (e.g. type of a {@link GPSFix}).
* @param type A {@link String} that specifies for which type the service should be registered
* @throws NoCorrespondingServiceRegisteredException Thrown, if no service is registered for this type.
*/
ServiceType findService(String type) throws NoCorrespondingServiceRegisteredException;
/**
* Sets a fallback service (optional), that is used if no service is registered for a {@code type}.
* This should be a generic service, that can deal with any {@code type}, and provides a
* "better-than-nothing" implementation, which will be returned instead of throwing a
* {@link NoCorrespondingServiceRegisteredException}.
* <p>
* This method does not need to be implemented, but can remain a stub, if no fallback behaviour
* is desired.
*/
void setFallbackService(ServiceType fallback);
}
@@ -0,0 +1,18 @@
package com.sap.sailing.domain.common.racelog.tracking;
/**
* A factory for creating {@link TypeBasedServiceFinder}s, for a specific type of service.
* The desired service type is specified by the {@link Class} object passed to the
* {@link #createServiceFinder(Class)} method.
*
* The created {@link TypeBasedServiceFinder} can then be used to find the desired
* service for a specific type. E.g., there may be a persistence service interface for
* {@link GPSFix}es, and there are several different service registered, depending on the type
* of {@link GPSFix}. The service finder then can find the appropriate service for each fix.
* @author Fredrik Teschke
*
*/
public interface TypeBasedServiceFinderFactory {
<ServiceT> TypeBasedServiceFinder<ServiceT> createServiceFinder(Class<ServiceT> clazz);
}
@@ -1,4 +1,5 @@
package com.sap.sailing.domain.confidence;
package com.sap.sailing.domain.common.scalablevalue;
/**
* A {@link ScalableValue} where the <code>ValueType</code> and the <code>AveragesTo</code> type are both the same because
@@ -1,4 +1,4 @@
package com.sap.sailing.domain.confidence;
package com.sap.sailing.domain.common.scalablevalue;
import java.io.Serializable;
@@ -1,4 +1,4 @@
package com.sap.sailing.domain.confidence;
package com.sap.sailing.domain.common.scalablevalue;
public interface ScalableValue<ValueType, AveragesTo> {
ScalableValue<ValueType, AveragesTo> multiply(double factor);
@@ -1,9 +1,9 @@
package com.sap.sailing.domain.base.impl;
package com.sap.sailing.domain.common.scalablevalue.impl;
import com.sap.sailing.domain.base.BearingWithConfidence.DoublePair;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.DoublePair;
import com.sap.sailing.domain.common.impl.RadianBearingImpl;
import com.sap.sailing.domain.confidence.ScalableValue;
import com.sap.sailing.domain.common.scalablevalue.ScalableValue;
public class ScalableBearing implements ScalableValue<DoublePair, Bearing> {
private final double sin;
@@ -1,8 +1,8 @@
package com.sap.sailing.domain.base.impl;
package com.sap.sailing.domain.common.scalablevalue.impl;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.impl.RadianPosition;
import com.sap.sailing.domain.confidence.ScalableValue;
import com.sap.sailing.domain.common.scalablevalue.ScalableValue;
public class ScalablePosition implements ScalableValue<ScalablePosition, Position> {
private final double x, y, z;
@@ -1,8 +1,8 @@
package com.sap.sailing.domain.base.impl;
package com.sap.sailing.domain.common.scalablevalue.impl;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
import com.sap.sailing.domain.confidence.ScalableValue;
import com.sap.sailing.domain.common.scalablevalue.ScalableValue;
public class ScalableSpeed implements ScalableValue<Double, Speed> {
private final double knots;
@@ -1,4 +1,4 @@
package com.sap.sailing.domain.base.impl;
package com.sap.sailing.domain.common.scalablevalue.impl;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.Speed;
@@ -7,7 +7,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.RadianBearingImpl;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.confidence.ScalableValue;
import com.sap.sailing.domain.common.scalablevalue.ScalableValue;
/**
* Separately scales speed and bearing. Instead of considering speed and bearing a single vector that can be scaled, the
@@ -1,5 +1,5 @@
package com.sap.sailing.domain.common.trackfiles;
public enum TrackFilesDataSource {
METADATA, COMPETITORS, BUOYS, WIND, MANEUVERS
METADATA, COMPETITORS, BUOYS, WIND, MANEUVERS
}
@@ -13,9 +13,6 @@ import java.util.logging.Logger;
import com.sap.sailing.declination.Declination;
import com.sap.sailing.declination.DeclinationService;
import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.base.impl.ScalableBearing;
import com.sap.sailing.domain.base.impl.ScalablePosition;
import com.sap.sailing.domain.base.impl.ScalableSpeed;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Speed;
@@ -24,7 +21,10 @@ import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.confidence.ScalableValue;
import com.sap.sailing.domain.common.scalablevalue.ScalableValue;
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableBearing;
import com.sap.sailing.domain.common.scalablevalue.impl.ScalablePosition;
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableSpeed;
import com.sap.sailing.domain.igtimiadapter.BulkFixReceiver;
import com.sap.sailing.domain.igtimiadapter.IgtimiConnection;
import com.sap.sailing.domain.igtimiadapter.IgtimiFixReceiverAdapter;
@@ -13,8 +13,20 @@ Require-Bundle: com.sap.sailing.mongodb,
com.sap.sailing.domain.shared.android,
com.sap.sailing.server.gateway.serialization;bundle-version="1.0.0"
Export-Package: com.sap.sailing.domain.persistence,
com.sap.sailing.domain.persistence.impl;x-friends:="com.sap.sailing.mongodb.test,com.sap.sailing.domain.swisstimingadapter.test,com.sap.sailing.domain.persistence.test",
com.sap.sailing.domain.persistence.media
com.sap.sailing.domain.persistence.impl;
x-friends:="com.sap.sailing.domain.persistence.test,
com.sap.sailing.domain.swisstimingadapter.test,
com.sap.sailing.mongodb.test,
com.sap.sailing.server.gateway.test,
com.sap.sailing.domain.racelogtrackingadapter.testsupport,
com.sap.sailing.domain.racelogtrackingadapter.test",
com.sap.sailing.domain.persistence.media,
com.sap.sailing.domain.persistence.racelog.tracking,
com.sap.sailing.domain.persistence.racelog.tracking.impl;
x-friends:="com.sap.sailing.domain.racelogtrackingadapter.testsupport,
com.sap.sailing.mongodb.test,
com.sap.sailing.domain.racelogtrackingadapter.test,
com.sap.sailing.server"
Bundle-ActivationPolicy: lazy
Import-Package: org.json.simple,
org.json.simple.parser,
@@ -1,115 +1,114 @@
package com.sap.sailing.domain.persistence;
import java.io.Serializable;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
/**
* Offers methods to construct {@link DBObject MongoDB objects} from domain objects.
*
* @author Axel Uhl (d043530)
*
*/
public interface MongoObjectFactory {
/**
* Registers for changes of the wind coming from <code>windSource</code> on the <code>trackedRace</code>. Each
* update received will be appended to the MongoDB and can later be retrieved. The key used to identify the race is
* the {@link RaceDefinition#getName() race name} and the {@link Regatta#getName() regatta name}.
*/
void addWindTrackDumper(TrackedRegatta trackedRegatta, TrackedRace trackedRace, WindSource windSource);
/**
* Stores the configuration data of <code>leaderboard</code> in the Mongo DB associated with this
* factory.
*/
void storeLeaderboard(Leaderboard leaderboard);
/**
* Removes the leaderboard named <code>name</code> from the database.
*/
void removeLeaderboard(String leaderboardName);
void renameLeaderboard(String oldName, String newName);
/**
* Stores the group, if it doesn't exist or updates it. Leaderboards in the group, which aren't stored in the
* database, will be stored. If the leaderboard group has an {@link LeaderboardGroup#getOverallLeaderboard() overall
* leaderboard}, it will be stored / updated as well.
*/
void storeLeaderboardGroup(LeaderboardGroup leaderboardGroup);
/**
* Removes the group with the name <code>groupName</code> from the database.
*/
void removeLeaderboardGroup(String groupName);
/**
* Renames the group with the name <code>oldName</code>.
*/
void renameLeaderboardGroup(String oldName, String newName);
/**
* Stores the event with its name, venue and the venue's course areas. The regattas obtained by
* {@link Event#getRegattas()} are <em>not</em> stored by this call. They need to be stored separately
* by calls to {@link #storeRegatta} where a reference to their owning event is stored.
*/
void storeEvent(Event event);
/**
* Renames the event with the name <code>oldName</code>.
*/
void renameEvent(Serializable id, String newName);
/**
* Removes the event named <code>eventName</code> from the database.
*/
void removeEvent(Serializable id);
/**
* Stores the regatta together with its name, {@link Series} definitions and an optional link to the
* {@link Event} to which the regatta belongs.
* @param oldSeriesNameNewName
*/
void storeRegatta(Regatta regatta);
void removeRegatta(Regatta regatta);
void storeRegattaForRaceID(String id, Regatta regatta);
void removeRegattaForRaceID(String raceIDAsString, Regatta regatta);
/**
* Stores a competitor, including the team and boat. This should not be done for competitors for which
* the master data is supplied by other systems, such as TracTrac, but rather for smartphone tracking,
* where this data is otherwise not recoverable.
* @param competitor the competitor to store/update in the database
*/
void storeCompetitor(Competitor competitor);
void removeAllCompetitors();
void removeCompetitor(Competitor competitor);
DB getDatabase();
void storeDeviceConfiguration(DeviceConfigurationMatcher matcher, DeviceConfiguration configuration);
void removeDeviceConfiguration(DeviceConfigurationMatcher matcher);
void removeRaceLog(RaceLogIdentifier identifier);
}
package com.sap.sailing.domain.persistence;
import java.io.Serializable;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
/**
* Offers methods to construct {@link DBObject MongoDB objects} from domain objects.
*
* @author Axel Uhl (d043530)
*
*/
public interface MongoObjectFactory {
/**
* Registers for changes of the wind coming from <code>windSource</code> on the <code>trackedRace</code>. Each
* update received will be appended to the MongoDB and can later be retrieved. The key used to identify the race is
* the {@link RaceDefinition#getName() race name} and the {@link Regatta#getName() regatta name}.
*/
void addWindTrackDumper(TrackedRegatta trackedRegatta, TrackedRace trackedRace, WindSource windSource);
/**
* Stores the configuration data of <code>leaderboard</code> in the Mongo DB associated with this
* factory.
*/
void storeLeaderboard(Leaderboard leaderboard);
/**
* Removes the leaderboard named <code>name</code> from the database.
*/
void removeLeaderboard(String leaderboardName);
void renameLeaderboard(String oldName, String newName);
/**
* Stores the group, if it doesn't exist or updates it. Leaderboards in the group, which aren't stored in the
* database, will be stored. If the leaderboard group has an {@link LeaderboardGroup#getOverallLeaderboard() overall
* leaderboard}, it will be stored / updated as well.
*/
void storeLeaderboardGroup(LeaderboardGroup leaderboardGroup);
/**
* Removes the group with the name <code>groupName</code> from the database.
*/
void removeLeaderboardGroup(String groupName);
/**
* Renames the group with the name <code>oldName</code>.
*/
void renameLeaderboardGroup(String oldName, String newName);
/**
* Stores the event with its name, venue and the venue's course areas. The regattas obtained by
* {@link Event#getRegattas()} are <em>not</em> stored by this call. They need to be stored separately
* by calls to {@link #storeRegatta} where a reference to their owning event is stored.
*/
void storeEvent(Event event);
/**
* Renames the event with the name <code>oldName</code>.
*/
void renameEvent(Serializable id, String newName);
/**
* Removes the event named <code>eventName</code> from the database.
*/
void removeEvent(Serializable id);
/**
* Stores the regatta together with its name, {@link Series} definitions and an optional link to the
* {@link Event} to which the regatta belongs.
* @param oldSeriesNameNewName
*/
void storeRegatta(Regatta regatta);
void removeRegatta(Regatta regatta);
void storeRegattaForRaceID(String id, Regatta regatta);
void removeRegattaForRaceID(String raceIDAsString, Regatta regatta);
/**
* Stores a competitor, including the team and boat. This should not be done for competitors for which
* the master data is supplied by other systems, such as TracTrac, but rather for smartphone tracking,
* where this data is otherwise not recoverable.
* @param competitor the competitor to store/update in the database
*/
void storeCompetitor(Competitor competitor);
void removeAllCompetitors();
void removeCompetitor(Competitor competitor);
DB getDatabase();
void storeDeviceConfiguration(DeviceConfigurationMatcher matcher, DeviceConfiguration configuration);
void removeDeviceConfiguration(DeviceConfigurationMatcher matcher);
void removeRaceLog(RaceLogIdentifier identifier);
}
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.persistence;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.persistence.impl.PersistenceFactoryImpl;
import com.sap.sailing.mongodb.MongoDBService;
@@ -9,6 +10,9 @@ public interface PersistenceFactory {
DomainObjectFactory getDefaultDomainObjectFactory();
DomainObjectFactory getDomainObjectFactory(MongoDBService mongoDBService, DomainFactory baseDomainFactory);
DomainObjectFactory getDomainObjectFactory(MongoDBService mongoDBService, DomainFactory baseDomainFactory, TypeBasedServiceFinderFactory serviceFinderFactory);
MongoObjectFactory getDefaultMongoObjectFactory();
MongoObjectFactory getMongoObjectFactory(MongoDBService mongoDBService);
MongoObjectFactory getDefaultMongoObjectFactory(TypeBasedServiceFinderFactory serviceFinderFactory);
MongoObjectFactory getMongoObjectFactory(MongoDBService mongoDBService, TypeBasedServiceFinderFactory serviceFinderFactory);
}
@@ -6,14 +6,13 @@ import org.osgi.framework.BundleContext;
import com.sap.sailing.mongodb.MongoDBService;
public class Activator implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
for (CollectionNames name : CollectionNames.values())
MongoDBService.INSTANCE.registerExclusively(CollectionNames.class, name.name());
}
@Override
public void stop(BundleContext context) throws Exception {
}
@Override
public void start(BundleContext context) throws Exception {
for (CollectionNames name : CollectionNames.values())
MongoDBService.INSTANCE.registerExclusively(CollectionNames.class, name.name());
}
@Override
public void stop(BundleContext context) throws Exception {
}
}
@@ -25,7 +25,7 @@ public enum CollectionNames {
LEADERBOARD_GROUPS,
/**
* Top-level event information about events such as Kiel Week 2011, or IDM Travemünde 2011, including name and
* Top-level event information about events such as Kiel Week 2011, or IDM Travem�nde 2011, including name and
* course areas.
*/
EVENTS,
@@ -62,5 +62,10 @@ public enum CollectionNames {
/**
* Stores configurations for mobile devices.
*/
CONFIGURATIONS;
CONFIGURATIONS,
/**
* Stores {@link GPSFix}es
*/
GPS_FIXES,
}
@@ -77,7 +77,8 @@ public enum FieldNames {
WAYPOINT_PASSINGINSTRUCTIONS, CONTROLPOINT, CONTROLPOINT_CLASS, MARK_ID, MARK_COLOR, MARK_NAME, MARK_PATTERN, MARK_SHAPE, MARK_TYPE,
CONTROLPOINT_VALUE, CONTROLPOINTWITHTWOMARKS_ID, CONTROLPOINTWITHTWOMARKS_NAME, CONTROLPOINTWITHTWOMARKS_LEFT, CONTROLPOINTWITHTWOMARKS_RIGHT,
RACE_LOG_POSITIONED_COMPETITORS, RACE_LOG_PATHFINDER_ID, RACE_LOG_GATE_LINE_OPENING_TIME, RACE_LOG_GOLF_DOWN_TIME, RACE_LOG_START_PROCEDURE_TYPE,
RACE_LOG_PROTEST_START_TIME, RACE_LOG_COURSE_DESIGN_NAME,
RACE_LOG_PROTEST_START_TIME, RACE_LOG_COURSE_DESIGN_NAME, RACE_LOG_REVOKED_EVENT_ID, RACE_LOG_FROM, RACE_LOG_TO, RACE_LOG_MARK, RACE_LOG_DEVICE_MAPPING_EVENT_ID,
RACE_LOG_CLOSING_TIMEPOINT,
/** @deprecated Replaced by WAYPOINT_PASSINGINSTRUCTIONS, still used to migrate old races*/ @Deprecated WAYPOINT_PASSINGSIDE,
/** @deprecated Replaced by CONTROLPOINTWITHTWOMARKS_ID, still used to migrate old races*/ @Deprecated GATE_ID,
/** @deprecated Replaced by CONTROLPOINTWITHTWOMARKS_NAME, still used to migrate old races*/ @Deprecated GATE_NAME,
@@ -88,5 +89,8 @@ public enum FieldNames {
// configurations
CONFIGURATION_MATCHER, CONFIGURATION_CONFIG, CONFIGURATION_MATCHER_ID, CONFIGURATION_MATCHER_TYPE, CONFIGURATION_MATCHER_CLIENTS,
CONFIGURATION_CONFIG_ALLOWED_COURSE_AREA_NAMES, CONFIGURATION_CONFIG_MIN_ROUNDS, CONFIGURATION_CONFIG_MAX_ROUNDS, CONFIGURATION_CONFIG_RESULTS_MAIL,
CONFIGURATION_CONFIG_PROCEDURES;
CONFIGURATION_CONFIG_PROCEDURES,
// GPSFixes
DEVICE_TYPE_SPECIFIC_ID, DEVICE_ID, DEVICE_TYPE, GPSFIX_TYPE, GPSFIX, DEVICE_STRING_REPRESENTATION,
}
@@ -1,114 +1,169 @@
package com.sap.sailing.domain.persistence.impl;
import java.util.logging.Logger;
import com.mongodb.DBObject;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.racelog.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.RaceLogFinishPositioningConfirmedEvent;
import com.sap.sailing.domain.racelog.RaceLogFinishPositioningListChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor {
private final RaceLogIdentifier raceLogIdentifier;
private final MongoObjectFactoryImpl mongoObjectFactory;
final static Logger logger = Logger.getLogger(MongoRaceLogStoreVisitor.class.getName());
public MongoRaceLogStoreVisitor(RaceLogIdentifier identifier, MongoObjectFactory mongoObjectFactory) {
super();
this.raceLogIdentifier = identifier;
this.mongoObjectFactory = (MongoObjectFactoryImpl) mongoObjectFactory;
}
@Override
public void visit(RaceLogFlagEvent event) {
DBObject flagEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(flagEventTrackEntry);
}
@Override
public void visit(RaceLogPassChangeEvent event) {
DBObject passChangeEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(passChangeEventTrackEntry);
}
@Override
public void visit(RaceLogRaceStatusEvent event) {
DBObject raceStatusEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(raceStatusEventTrackEntry);
}
@Override
public void visit(RaceLogStartTimeEvent event) {
DBObject startTimeEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(startTimeEventTrackEntry);
}
@Override
public void visit(RaceLogCourseAreaChangedEvent event) {
DBObject courseAreaChangedEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(courseAreaChangedEventTrackEntry);
}
@Override
public void visit(RaceLogCourseDesignChangedEvent event) {
DBObject courseDesignChangedEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(courseDesignChangedEventTrackEntry);
}
@Override
public void visit(RaceLogFinishPositioningListChangedEvent event) {
DBObject finishPositioningListChangedEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(finishPositioningListChangedEventTrackEntry);
}
@Override
public void visit(RaceLogFinishPositioningConfirmedEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogPathfinderEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogGateLineOpeningTimeEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogStartProcedureChangedEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogProtestStartTimeEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogWindFixEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
}
package com.sap.sailing.domain.persistence.impl;
import java.util.logging.Logger;
import com.mongodb.DBObject;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.racelog.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.RaceLogFinishPositioningConfirmedEvent;
import com.sap.sailing.domain.racelog.RaceLogFinishPositioningListChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.RevokeEvent;
import com.sap.sailing.domain.racelog.tracking.CloseOpenEndedDeviceMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DefineMarkEvent;
import com.sap.sailing.domain.racelog.tracking.DenoteForTrackingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceCompetitorMappingEvent;
import com.sap.sailing.domain.racelog.tracking.DeviceMarkMappingEvent;
import com.sap.sailing.domain.racelog.tracking.RegisterCompetitorEvent;
import com.sap.sailing.domain.racelog.tracking.StartTrackingEvent;
public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor {
private final RaceLogIdentifier raceLogIdentifier;
private final MongoObjectFactoryImpl mongoObjectFactory;
final static Logger logger = Logger.getLogger(MongoRaceLogStoreVisitor.class.getName());
public MongoRaceLogStoreVisitor(RaceLogIdentifier identifier, MongoObjectFactory mongoObjectFactory) {
super();
this.raceLogIdentifier = identifier;
this.mongoObjectFactory = (MongoObjectFactoryImpl) mongoObjectFactory;
}
@Override
public void visit(RaceLogFlagEvent event) {
DBObject flagEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(flagEventTrackEntry);
}
@Override
public void visit(RaceLogPassChangeEvent event) {
DBObject passChangeEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(passChangeEventTrackEntry);
}
@Override
public void visit(RaceLogRaceStatusEvent event) {
DBObject raceStatusEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(raceStatusEventTrackEntry);
}
@Override
public void visit(RaceLogStartTimeEvent event) {
DBObject startTimeEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(startTimeEventTrackEntry);
}
@Override
public void visit(RaceLogCourseAreaChangedEvent event) {
DBObject courseAreaChangedEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(courseAreaChangedEventTrackEntry);
}
@Override
public void visit(RaceLogCourseDesignChangedEvent event) {
DBObject courseDesignChangedEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(courseDesignChangedEventTrackEntry);
}
@Override
public void visit(RaceLogFinishPositioningListChangedEvent event) {
DBObject finishPositioningListChangedEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(finishPositioningListChangedEventTrackEntry);
}
@Override
public void visit(RaceLogFinishPositioningConfirmedEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogPathfinderEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogGateLineOpeningTimeEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogStartProcedureChangedEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogProtestStartTimeEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RaceLogWindFixEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(DeviceCompetitorMappingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(DeviceMarkMappingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(DenoteForTrackingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(StartTrackingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RevokeEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(RegisterCompetitorEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(DefineMarkEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
@Override
public void visit(CloseOpenEndedDeviceMappingEvent event) {
DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
mongoObjectFactory.storeRaceLogEventEvent(object);
}
}
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.persistence.impl;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.PersistenceFactory;
@@ -11,7 +12,6 @@ public class PersistenceFactoryImpl implements PersistenceFactory {
private final MongoObjectFactory defaultMongoObjectFactory;
public PersistenceFactoryImpl() {
super();
this.defaultDomainObjectFactory = new DomainObjectFactoryImpl(MongoDBService.INSTANCE.getDB(), DomainFactory.INSTANCE);
this.defaultMongoObjectFactory = new MongoObjectFactoryImpl(MongoDBService.INSTANCE.getDB());
}
@@ -31,14 +31,29 @@ public class PersistenceFactoryImpl implements PersistenceFactory {
return new DomainObjectFactoryImpl(mongoDBService.getDB(), baseDomainFactory);
}
@Override
public DomainObjectFactory getDomainObjectFactory(MongoDBService mongoDBService, DomainFactory baseDomainFactory,
TypeBasedServiceFinderFactory serviceFinderFactory) {
return new DomainObjectFactoryImpl(mongoDBService.getDB(), baseDomainFactory, serviceFinderFactory);
}
@Override
public MongoObjectFactory getDefaultMongoObjectFactory() {
return defaultMongoObjectFactory;
}
@Override
public MongoObjectFactory getDefaultMongoObjectFactory(TypeBasedServiceFinderFactory serviceFinderFactory) {
return new MongoObjectFactoryImpl(this.defaultMongoObjectFactory.getDatabase(), serviceFinderFactory);
}
@Override
public MongoObjectFactory getMongoObjectFactory(MongoDBService mongoDBService) {
return new MongoObjectFactoryImpl(mongoDBService.getDB());
}
@Override
public MongoObjectFactory getMongoObjectFactory(MongoDBService mongoDBService, TypeBasedServiceFinderFactory serviceFinderFactory) {
return new MongoObjectFactoryImpl(mongoDBService.getDB(), serviceFinderFactory);
}
}
@@ -0,0 +1,6 @@
package com.sap.sailing.domain.persistence.racelog.tracking;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifierSerializationHandler;
public interface DeviceIdentifierMongoHandler extends DeviceIdentifierSerializationHandler<Object> {
}
@@ -0,0 +1,16 @@
package com.sap.sailing.domain.persistence.racelog.tracking;
import com.mongodb.DBObject;
import com.sap.sailing.domain.common.racelog.tracking.TransformationHandler;
import com.sap.sailing.domain.tracking.GPSFix;
/**
* For GPS Fixes, the fully qualified class name is the type used to identify
* the handlers, as the fixes are domain objects and are not intended to carry
* some separate type attribute.
*
* @author Fredrik Teschke
*
*/
public interface GPSFixMongoHandler extends TransformationHandler<GPSFix, DBObject> {
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.persistence.racelog.tracking;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
public interface MongoGPSFixStore extends GPSFixStore {
}
@@ -0,0 +1,22 @@
package com.sap.sailing.domain.persistence.racelog.tracking;
import java.net.UnknownHostException;
import com.mongodb.MongoException;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoGPSFixStoreFactoryImpl;
public interface MongoGPSFixStoreFactory {
MongoGPSFixStoreFactory INSTANCE = new MongoGPSFixStoreFactoryImpl();
/**
* Gets the default Mongo store based on the properties mongo.hostname[=localhost], mongo.port[=27017]
* and mongo.dbName[=&lt;contents of constant {@link #DEFAULT_DB_NAME}&gt;] specified in the bundle context
*/
MongoGPSFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory,
TypeBasedServiceFinderFactory serviceFinderFactory)
throws UnknownHostException, MongoException;
}
@@ -0,0 +1,40 @@
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
public class GPSFixMongoHandlerImpl implements GPSFixMongoHandler {
private final MongoObjectFactoryImpl mof;
private final DomainObjectFactoryImpl dof;
public GPSFixMongoHandlerImpl(MongoObjectFactory mof, DomainObjectFactory dof) {
this.mof = (MongoObjectFactoryImpl) mof;
this.dof = (DomainObjectFactoryImpl) dof;
}
@Override
public DBObject transformForth(GPSFix fix) throws IllegalArgumentException {
DBObject result = new BasicDBObject();
mof.storeTimed(fix, result);
mof.storePositioned(fix, result);
return result;
}
@Override
public GPSFix transformBack(DBObject object) {
DBObject dbObject = (DBObject) object;
TimePoint timePoint = dof.loadTimePoint(dbObject);
Position position = dof.loadPosition(dbObject);
return new GPSFixImpl(position, timePoint);
}
}
@@ -0,0 +1,43 @@
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
public class GPSFixMovingMongoHandlerImpl implements GPSFixMongoHandler {
private final MongoObjectFactoryImpl mof;
private final DomainObjectFactoryImpl dof;
public GPSFixMovingMongoHandlerImpl(MongoObjectFactory mof, DomainObjectFactory dof) {
this.mof = (MongoObjectFactoryImpl) mof;
this.dof = (DomainObjectFactoryImpl) dof;
}
@Override
public DBObject transformForth(GPSFix fix) throws IllegalArgumentException {
DBObject result = new BasicDBObject();
mof.storeTimed(fix, result);
mof.storePositioned(fix, result);
mof.storeSpeedWithBearing(((GPSFixMoving) fix).getSpeed(), result);
return result;
}
@Override
public GPSFix transformBack(DBObject dbObject) {
TimePoint timePoint = dof.loadTimePoint(dbObject);
Position position = dof.loadPosition(dbObject);
SpeedWithBearing speed = dof.loadSpeedWithBearing(dbObject);
return new GPSFixMovingImpl(position, timePoint, speed);
}
}
@@ -0,0 +1,19 @@
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
import java.net.UnknownHostException;
import com.mongodb.MongoException;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStore;
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStoreFactory;
public class MongoGPSFixStoreFactoryImpl implements MongoGPSFixStoreFactory {
@Override
public MongoGPSFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory,
DomainObjectFactory domainObjectFactory, TypeBasedServiceFinderFactory serviceFinderFactory)
throws UnknownHostException, MongoException {
return new MongoGPSFixStoreImpl(mongoObjectFactory, domainObjectFactory, serviceFinderFactory);
}
}
@@ -0,0 +1,165 @@
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.impl.FieldNames;
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStore;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.DeviceMapping;
import com.sap.sailing.domain.racelog.tracking.GPSFixReceivedListener;
import com.sap.sailing.domain.racelog.tracking.analyzing.impl.DeviceCompetitorMappingFinder;
import com.sap.sailing.domain.racelog.tracking.analyzing.impl.DeviceMarkMappingFinder;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.GPSFixMoving;
public class MongoGPSFixStoreImpl implements MongoGPSFixStore {
private static final Logger logger = Logger.getLogger(MongoGPSFixStore.class.getName());
private final TypeBasedServiceFinder<GPSFixMongoHandler> fixServiceFinder;
private final TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceServiceFinder;
private final DBCollection collection;
private final MongoObjectFactoryImpl mongoOF;
private final ConcurrentHashMap<Object, GPSFixReceivedListener> listeners = new ConcurrentHashMap<>();
public MongoGPSFixStoreImpl(MongoObjectFactory mongoObjectFactory,
DomainObjectFactory domainObjectFactory, TypeBasedServiceFinderFactory serviceFinderFactory) {
mongoOF = (MongoObjectFactoryImpl) mongoObjectFactory;
if (serviceFinderFactory != null) {
fixServiceFinder = serviceFinderFactory.createServiceFinder(GPSFixMongoHandler.class);
deviceServiceFinder = serviceFinderFactory.createServiceFinder(DeviceIdentifierMongoHandler.class);
} else {
fixServiceFinder = null;
deviceServiceFinder = null;
}
collection = mongoOF.getGPSFixCollection();
}
private GPSFix loadGPSFix(DBObject object) throws TransformationException, NoCorrespondingServiceRegisteredException {
String type = (String) object.get(FieldNames.GPSFIX_TYPE.name());
DBObject fixObject = (DBObject) object.get(FieldNames.GPSFIX.name());
return fixServiceFinder.findService(type).transformBack(fixObject);
}
private <FixT extends GPSFix> void loadTrack(DynamicGPSFixTrack<?, FixT> track, DeviceIdentifier device,
TimePoint from, TimePoint to, boolean inclusive) throws NoCorrespondingServiceRegisteredException {
long fromMillis = from.asMillis() - (inclusive ? 1 : 0);
long toMillis = to.asMillis() + (inclusive ? 1 : 0);
Object dbDeviceId = null;
try {
dbDeviceId = MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device);
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
logger.log(Level.WARNING, "Could not serialize Device ID for MongoDB: " + e.getMessage());
return;
}
DBObject query = QueryBuilder.start(FieldNames.DEVICE_ID.name()).is(dbDeviceId)
.and(FieldNames.TIME_AS_MILLIS.name()).greaterThan(fromMillis)
.and(FieldNames.TIME_AS_MILLIS.name()).lessThan(toMillis).get();
DBCursor result = collection.find(query);
for (DBObject fixObject : result) {
try {
@SuppressWarnings("unchecked")
FixT fix = (FixT) loadGPSFix(fixObject);
track.add(fix);
} catch (TransformationException e) {
logger.log(Level.WARNING, "Could not read fix from MongoDB: " + fixObject);
} catch (ClassCastException e) {
String type = (String) fixObject.get(FieldNames.GPSFIX_TYPE.name());
logger.log(Level.WARNING, "Unexpected fix type (" + type + ") encountered when trying to load track for " + track.getTrackedItem());
}
}
}
@Override
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RaceLog raceLog, Competitor competitor) {
List<DeviceMapping<Competitor>> mappings = new DeviceCompetitorMappingFinder(raceLog).analyze().get(competitor);
if (mappings != null) {
for (DeviceMapping<Competitor> mapping : mappings) {
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
}
}
}
@Override
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RaceLog raceLog, Mark mark) {
List<DeviceMapping<Mark>> mappings = new DeviceMarkMappingFinder(raceLog).analyze().get(mark);
if (mappings != null) {
for (DeviceMapping<Mark> mapping : mappings) {
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
}
}
}
@Override
public void storeFix(DeviceIdentifier device, GPSFix fix) {
try {
Object dbDeviceId = MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device);
String type = fix.getClass().getName();
Object fixObject = fixServiceFinder.findService(type).transformForth(fix);
DBObject entry = new BasicDBObjectBuilder()
.add(FieldNames.DEVICE_ID.name(), dbDeviceId)
.add(FieldNames.GPSFIX_TYPE.name(), type)
.add(FieldNames.GPSFIX.name(), fixObject).get();
mongoOF.storeTimed(fix, entry);
collection.insert(entry);
} catch (TransformationException e) {
logger.log(Level.WARNING, "Could not store fix in MongoDB");
e.printStackTrace();
}
notifyListeners(device, fix);
}
private void notifyListeners(DeviceIdentifier device, GPSFix fix) {
for (GPSFixReceivedListener listener : listeners.values()) {
listener.fixReceived(device, fix);
}
}
@Override
public void addListener(GPSFixReceivedListener listener) {
listeners.put(listener.hashCode(), listener);
}
@Override
public void removeListener(GPSFixReceivedListener listener) {
listeners.remove(listener.hashCode());
}
@Override
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, DeviceMapping<Competitor> mapping) {
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
}
@Override
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping) {
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
}
}
@@ -0,0 +1,17 @@
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.impl.PlaceHolderDeviceIdentifierSerializationHandler;
public class PlaceHolderDeviceIdentifierMongoHandler extends PlaceHolderDeviceIdentifierSerializationHandler
implements DeviceIdentifierMongoHandler {
@Override
public DeviceIdentifier deserialize(Object serialized, String type, String stringRepresentation)
throws TransformationException {
return deserialize((String) serialized, type, stringRepresentation);
}
}
@@ -0,0 +1,7 @@
<?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="output" path="bin"/>
</classpath>
@@ -0,0 +1 @@
bin
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.sap.sailing.domain.racelogtrackingadapter.test</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:52:18 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 @@
#Thu Aug 25 17:11:24 CEST 2011
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false
@@ -0,0 +1,19 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Smartphone Adapter Test
Bundle-SymbolicName: com.sap.sailing.domain.racelogtrackingadapter.test
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Fragment-Host: com.sap.sailing.domain.racelogtrackingadapter
Require-Bundle: org.junit4;bundle-version="4.8.2",
com.sap.sailing.domain.racelogtrackingadapter.testsupport,
org.mockito.mockito-core;bundle-version="1.9.5",
org.objenesis;bundle-version="1.3.0",
org.hamcrest;bundle-version="1.1.0",
com.mongodb.driver;bundle-version="2.6.2"
Import-Package: com.sap.sailing.domain.persistence.impl,
com.sap.sailing.domain.persistence.racelog.tracking.impl,
com.sap.sailing.domain.tractracadapter,
com.sap.sailing.server.impl,
javax.servlet.http;version="2.5.0"
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,
@@ -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.domain.racelogtrackingadapter.test</artifactId>
<packaging>eclipse-test-plugin</packaging>
</project>
Whitespace-only changes.
@@ -0,0 +1,82 @@
package com.sap.sailing.domain.racelogtracking.test;
import static com.sap.sailing.domain.common.impl.Util.size;
import static junit.framework.Assert.assertEquals;
import org.junit.After;
import org.junit.Before;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoGPSFixStoreImpl;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
import com.sap.sailing.domain.racelog.impl.RaceLogEventAuthorImpl;
import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockDeviceAndSessioinIdentifierWithGPSFixesDeserializer;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.gateway.deserialization.impl.DeviceAndSessionIdentifierWithGPSFixesDeserializer;
import com.sap.sailing.server.impl.RacingEventServiceImpl;
public class AbstractGPSFixStoreTest {
protected RacingEventService service;
protected final MockSmartphoneImeiServiceFinderFactory serviceFinderFactory = new MockSmartphoneImeiServiceFinderFactory();
DeviceAndSessionIdentifierWithGPSFixesDeserializer deserializer =
new MockDeviceAndSessioinIdentifierWithGPSFixesDeserializer();
protected final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
protected RaceLog raceLog;
protected GPSFixStore store;
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null);
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
private final RaceLogEventAuthor author = new RaceLogEventAuthorImpl("author", 0);
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
return new GPSFixMovingImpl(new DegreePosition(lat, lng),
new MillisecondsTimePoint(millis), new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
}
@Before
public void setServiceAndRaceLog() {
service = new RacingEventServiceImpl(null, null, serviceFinderFactory);
raceLog = new RaceLogImpl("racelog");
store = new MongoGPSFixStoreImpl(service.getMongoObjectFactory(), service.getDomainObjectFactory(),
serviceFinderFactory);
}
@After
public void after() {
MongoObjectFactoryImpl mongoOF = (MongoObjectFactoryImpl) service.getMongoObjectFactory();
mongoOF.getGPSFixCollection().drop();
}
protected void map(Competitor comp, DeviceIdentifier device, long from, long to) {
raceLog.add(RaceLogEventFactory.INSTANCE.createDeviceCompetitorMappingEvent(MillisecondsTimePoint.now(), author, device,
comp, 0, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
}
protected void map(Mark mark, DeviceIdentifier device, long from, long to) {
raceLog.add(RaceLogEventFactory.INSTANCE.createDeviceMarkMappingEvent(MillisecondsTimePoint.now(), author, device,
mark, 0, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
}
protected void testLength(Track<?> track, long expected) {
track.lockForRead();
assertEquals(expected, size(track.getRawFixes()));
track.unlockAfterRead();
}
}
@@ -0,0 +1,76 @@
package com.sap.sailing.domain.racelogtracking.test;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
public abstract class AbstractJsonOverHttpTest {
protected static final String URL_BASE = "127.0.0.1";
protected static final int PORT = 8888;
protected static final String URL_SS = "/sailingserver";
protected static final String URL_TR = "/tracking";
protected static final String URL_RF = "/recordFixes";
protected String getUrl(String endOfUrl) {
return "http://" + URL_BASE + ":" + PORT + endOfUrl;
}
protected String executeRequest(String method, String targetURL, String body) throws IOException {
// Create connection
URL url = new URL(targetURL);
System.out.println(url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(method);
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoInput(true);
// Send request
if (method.equals("POST")) {
connection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(body);
}
InputStream is = null;
boolean error = false;
if (connection.getResponseCode() >= 400) {
is = connection.getErrorStream();
error = true;
} else {
is = connection.getInputStream();
}
if (is == null) {
return "";
}
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
if (error) {
System.err.println(response.toString());
return "";
}
return response.toString();
}
protected Object getJson(String url) throws IllegalStateException, IOException, ParseException {
return JSONValue.parseWithException(executeRequest("GET", url, ""));
}
}
@@ -0,0 +1,159 @@
package com.sap.sailing.domain.racelogtracking.test.impl;
import static com.sap.sailing.domain.common.impl.Util.size;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.UUID;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.CourseDataImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
import com.sap.sailing.domain.racelog.RaceLogEventFactory;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
import com.sap.sailing.domain.racelogtracking.impl.RaceLogTrackingAdapterFactoryImpl;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.impl.RacingEventServiceImpl;
public class CreateAndTrackWithRaceLogTest {
private RacingEventService service;
private final Fleet fleet = new FleetImpl("fleet");
private final String columnName = "column";
private RegattaLeaderboard leaderboard;
private RaceLogTrackingAdapter adapter;
private Regatta regatta;
private RaceLogEventAuthor author;
private GPSFixStore gpsFixStore;
private long time = 0;
private static final RaceLogEventFactory factory = RaceLogEventFactory.INSTANCE;
@Before
public void setup() {
service = new RacingEventServiceImpl(true, new MockSmartphoneImeiServiceFinderFactory());
gpsFixStore = service.getGPSFixStore();
service.getMongoObjectFactory().getDatabase().dropDatabase();
author = service.getServerAuthor();
Series series = new SeriesImpl("series", false, Collections.singletonList(fleet),
Collections.singletonList(columnName), service);
regatta = service.createRegatta("regatta", "Laser", UUID.randomUUID(), Collections.<Series>singletonList(series),
false, new HighPoint(), UUID.randomUUID());
leaderboard = service.addRegattaLeaderboard(regatta.getRegattaIdentifier(), "RegattaLeaderboard", new int[] {});
adapter = RaceLogTrackingAdapterFactoryImpl.INSTANCE.getAdapter(DomainFactory.INSTANCE);
}
@Test
public void hasRaceLog() {
assertNotNull(leaderboard.getRaceColumnByName(columnName).getRaceLog(fleet));
}
private TimePoint t() {
return new MillisecondsTimePoint(time++);
}
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void cantAddBeforeDenoting() throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception {
RaceColumn column = leaderboard.getRaceColumnByName(columnName);
exception.expect(RaceNotCreatedException.class);
adapter.startTracking(service, leaderboard, column, fleet);
}
private void testSize(Track<?> track, int expected) {
track.lockForRead();
assertEquals(expected, size(track.getRawFixes()));
track.unlockAfterRead();
}
@Test
public void canDenote_Add_Track() throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception {
RaceColumn column = leaderboard.getRaceColumnByName(columnName);
RaceLog raceLog = column.getRaceLog(fleet);
//can denote racelog for tracking
assertTrue(raceLog.isEmpty());
adapter.denoteRaceForRaceLogTracking(service, leaderboard, column, fleet, "race");
assertFalse(raceLog.isEmpty());
//add a mapping and one fix in, one out of mapping
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", null, null, null);
DeviceIdentifier dev1 = new SmartphoneImeiIdentifier("dev1");
raceLog.add(factory.createDeviceCompetitorMappingEvent(t(), author, dev1, comp1, 0, new MillisecondsTimePoint(0), new MillisecondsTimePoint(10)));
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(5), new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(5))));
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(15), new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(5))));
CourseBase course = new CourseDataImpl("test");
course.addWaypoint(0, new WaypointImpl(new MarkImpl("mark")));
raceLog.add(factory.createCourseDesignChangedEvent(t(), author, 0, course));
raceLog.add(factory.createRegisterCompetitorEvent(t(), author, 0, comp1));
//start tracking
adapter.startTracking(service, leaderboard, column, fleet);
//now there is a trackedrace
TrackedRace race = column.getTrackedRace(fleet);
assertNotNull(race);
//one fix should have been loaded from store
testSize(race.getTrack(comp1), 1);
//further fix arrives in race
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(7), new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(5))));
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(14), new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(5)))); //outside mapping range
testSize(race.getTrack(comp1), 2);
//add another mapping on the fly, other old fixes should be loaded
raceLog.add(factory.createDeviceCompetitorMappingEvent(t(), author, dev1, comp1, 0, new MillisecondsTimePoint(11), new MillisecondsTimePoint(20)));
testSize(race.getTrack(comp1), 4);
//add another fix in new mapping range
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(18), new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(5))));
testSize(race.getTrack(comp1), 5);
//stop tracking, then no more fixes arrive at race
service.getRaceTrackerById(raceLog.getId()).stop();
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(8), new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(5))));
testSize(race.getTrack(comp1), 5);
}
}
@@ -0,0 +1,64 @@
package com.sap.sailing.domain.racelogtracking.test.impl;
import static com.sap.sailing.domain.common.impl.Util.size;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.test.mock.MockDeviceAndSessioinIdentifierWithGPSFixesDeserializer;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelogtracking.servlet.RecordFixesPostServlet;
import com.sap.sailing.domain.racelogtracking.test.AbstractGPSFixStoreTest;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
import com.sap.sailing.server.gateway.deserialization.impl.DeviceAndSessionIdentifierWithGPSFixesDeserializer;
public class RecordFixesTest extends AbstractGPSFixStoreTest {
private RecordFixesPostServlet servlet;
private final DeviceAndSessionIdentifierWithGPSFixesDeserializer deserializer =
new MockDeviceAndSessioinIdentifierWithGPSFixesDeserializer();
private final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
@Before
public void setupServlet() {
servlet = new RecordFixesPostServlet();
servlet = spy(servlet);
when(servlet.getRequestDeserializer()).thenReturn(deserializer);
doReturn(service).when(servlet).getService();
}
@Test
public void areFixesStoredInDb() throws TransformationException, NoCorrespondingServiceRegisteredException {
map(comp, device, 0, 600);
int timepoint = 343;
List<GPSFix> fixes = new ArrayList<>();
fixes.add(createFix(timepoint, 0, 0, 0, 0));
fixes.add(createFix(timepoint+1, 0, 0, 0, 0));
Triple<DeviceIdentifier, Serializable, List<GPSFix>> data = new Triple<>(device, null, fixes);
servlet.process(null, data);
DynamicGPSFixMovingTrackImpl<Competitor> track = new DynamicGPSFixMovingTrackImpl<>(comp, 0);
store.loadCompetitorTrack(track, raceLog, comp);
track.lockForRead();
assertEquals(2, size(track.getRawFixes()));
assertEquals(timepoint, track.getFirstRawFix().getTimePoint().asMillis());
assertTrue(track.getFirstRawFix() instanceof GPSFixMoving);
track.unlockAfterRead();
}
}
@@ -0,0 +1,67 @@
package com.sap.sailing.domain.racelogtracking.test.impl;
import java.util.Arrays;
import java.util.Collections;
import org.junit.Test;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelogtracking.test.AbstractGPSFixStoreTest;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.TrackedRegattaImpl;
public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
@Test
public void areFixesStoredInDb() throws TransformationException, NoCorrespondingServiceRegisteredException, InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null);
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
DeviceIdentifier device2 = new SmartphoneImeiIdentifier("imei2");
DeviceIdentifier device3 = new SmartphoneImeiIdentifier("imei3");
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] {new WaypointImpl(mark), new WaypointImpl(mark2)}));
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] {comp, comp2}));
map(comp, device, 0, 600);
map(comp2, device2, 0, 600);
//reuse device for two marks
map(mark, device3, 0, 600);
map(mark2, device3, 0, 600);
store.storeFix(device, createFix(100, 10, 20, 30, 40));
store.storeFix(device, createFix(101, 10, 20, 30, 40));
store.storeFix(device2, createFix(100, 10, 20, 30, 40));
store.storeFix(device3, createFix(100, 10, 20, 30, 40));
store.storeFix(device3, createFix(100, 10, 20, 30, 40));
TrackedRegatta regatta = new TrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE, "regatta", boatClass, null, null, "a", null));
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline>emptyList(),
EmptyWindStore.INSTANCE, store, 0, 0, 0);
trackedRace.attachRaceLog(raceLog);
trackedRace.waitUntilNotLoading();
trackedRace.waitUntilLoadingFromGPSFixStoreComplete();
testLength(trackedRace.getTrack(comp), 2);
testLength(trackedRace.getTrack(comp2), 1);
testLength(trackedRace.getOrCreateTrack(mark), 1);
testLength(trackedRace.getOrCreateTrack(mark2), 1);
}
}
@@ -0,0 +1,107 @@
package com.sap.sailing.domain.racelogtracking.test.manual;
import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiJsonHandler;
import com.sap.sailing.domain.racelogtracking.test.AbstractJsonOverHttpTest;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.server.gateway.serialization.impl.DeviceAndSessionIdentifierWithGPSFixesSerializer;
import com.sap.sailing.server.gateway.serialization.impl.DeviceIdentifierJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.GPSFixMovingNmeaDTOJsonSerializer;
public class PostFixes extends AbstractJsonOverHttpTest {
protected static final SmartphoneImeiIdentifier device = new SmartphoneImeiIdentifier("a");
private final DeviceAndSessionIdentifierWithGPSFixesSerializer<SmartphoneImeiIdentifier, GPSFixMoving> fixSerializer =
new DeviceAndSessionIdentifierWithGPSFixesSerializer<>(DeviceIdentifierJsonSerializer.create(
new SmartphoneImeiJsonHandler(), SmartphoneImeiIdentifier.TYPE), new GPSFixMovingNmeaDTOJsonSerializer());
private void recordFix(GPSFixMoving... fix) throws IOException {
String request = fixSerializer.serialize(
new Triple<SmartphoneImeiIdentifier, Serializable, List<GPSFixMoving>>(
device, null, Arrays.asList(fix))).toJSONString();
executeRequest("POST", getUrl(URL_TR + "/recordFixes"), request);
}
private void recordFixes() {
final Timer timer = new Timer();
final Position p1 = new DegreePosition(54.427119, 10.182583);
final Position p2 = new DegreePosition(54.435707, 10.200779);
final Position p3 = new DegreePosition(54.425921, 10.188248);
final int nFirstLeg = 100;
final int nSecondLeg = 100;
final int n = nFirstLeg + nSecondLeg;
long period = 1000;
timer.scheduleAtFixedRate(new TimerTask() {
int i = 0;
GPSFix lastFix;
@Override
public void run() {
if (i++ > n)
timer.cancel();
Position start;
Position end;
int iLeg = i;
int nLeg;
if (i < nFirstLeg) {
start = p1;
end = p2;
nLeg = nFirstLeg;
} else {
start = p2;
end = p3;
iLeg -= nFirstLeg;
nLeg = nSecondLeg;
}
Distance distance = start.getDistance(end);
Bearing bearing = start.getBearingGreatCircle(end);
Position boat = start.translateGreatCircle(bearing, distance.scale(((double) iLeg) / nLeg));
GPSFix fix = new GPSFixImpl(boat, MillisecondsTimePoint.now());
SpeedWithBearing speed = lastFix == null ? new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0))
: lastFix.getSpeedAndBearingRequiredToReach(fix);
lastFix = fix;
try {
recordFix(new GPSFixMovingImpl(fix.getPosition(), fix.getTimePoint(), speed));
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0, period);
}
public void run() throws IOException, IllegalStateException, ParseException, InterruptedException {
recordFixes();
}
public static void main(String[] args) throws IllegalStateException, IOException, ParseException,
InterruptedException {
new PostFixes().run();
}
}
@@ -0,0 +1,7 @@
<?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.6"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.sap.sailing.domain.racelogtrackingadapter.testsupport</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>
@@ -1,8 +1,7 @@
#Wed Nov 02 13:57:42 CET 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false
@@ -0,0 +1,19 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Testsupport
Bundle-SymbolicName: com.sap.sailing.domain.racelogtrackingadapter.testsupport
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: com.sap.sailing.domain.shared.android,
com.sap.sailing.domain,
com.sap.sailing.domain.common,
com.mongodb.driver,
com.sap.sailing.domain.persistence,
com.sap.sailing.domain.racelogtrackingadapter,
com.sap.sailing.server.gateway.serialization;bundle-version="1.0.0",
org.json.simple;bundle-version="1.1.0",
org.mockito.mockito-core;bundle-version="1.9.5",
org.hamcrest;bundle-version="1.1.0",
org.junit4;bundle-version="4.8.2"
Export-Package: com.sap.sailing.domain.racelog.tracking.test.mock
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
@@ -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.domain.racelogtrackingadapter.testsupport</artifactId>
<packaging>eclipse-plugin</packaging>
</project>
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.server.gateway.deserialization.impl.DeviceAndSessionIdentifierWithGPSFixesDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.DeviceIdentifierJsonDeserializer;
public class MockDeviceAndSessioinIdentifierWithGPSFixesDeserializer extends
DeviceAndSessionIdentifierWithGPSFixesDeserializer {
public MockDeviceAndSessioinIdentifierWithGPSFixesDeserializer() {
super(new MockGPSFixJsonServiceFinder(),
DeviceIdentifierJsonDeserializer.create(new SmartphoneImeiJsonHandler(), SmartphoneImeiIdentifier.TYPE));
}
}
@@ -0,0 +1,19 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.NoCorrespondingServiceRegisteredException;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
public class MockEmptyServiceFinder<ServiceType> implements TypeBasedServiceFinder<ServiceType> {
private ServiceType fallback;
@Override
public ServiceType findService(String type) throws NoCorrespondingServiceRegisteredException {
return fallback;
}
@Override
public void setFallbackService(ServiceType fallback) {
this.fallback = fallback;
}
}
@@ -0,0 +1,19 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
/**
* A simplified implementation of the {@link TypeBasedServiceFinder} interface that, when the device type
* {@link SmartphoneImeiIdentifier#TYPE} is requested, returns a specific handler that was passed to this object's
* constructor.
*
* @author Fredrik Teschke
*
*/
public class MockEmptyServiceFinderFactory implements TypeBasedServiceFinderFactory {
@Override
public <ServiceT> TypeBasedServiceFinder<ServiceT> createServiceFinder(Class<ServiceT> clazz) {
return new MockEmptyServiceFinder<ServiceT>();
}
}
@@ -0,0 +1,24 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.GPSFixMovingJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.GPSFixMovingJsonSerializer;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
public class MockGPSFixJsonHandler implements GPSFixJsonHandler {
@Override
public JSONObject transformForth(GPSFix object) {
return new GPSFixMovingJsonSerializer().serialize((GPSFixMoving) object);
}
@Override
public GPSFix transformBack(JSONObject json) throws JsonDeserializationException {
return new GPSFixMovingJsonDeserializer().deserialize(json);
}
}
@@ -0,0 +1,21 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.server.gateway.deserialization.impl.GPSFixMovingJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
public class MockGPSFixJsonServiceFinder implements TypeBasedServiceFinder<GPSFixJsonHandler> {
private final MockGPSFixJsonHandler handler = new MockGPSFixJsonHandler();
@Override
public GPSFixJsonHandler findService(String fixType) {
if (fixType.equals(GPSFixMovingJsonDeserializer.TYPE)) {
return handler;
}
return null;
}
@Override
public void setFallbackService(GPSFixJsonHandler fallback) {
}
}
@@ -0,0 +1,26 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMongoHandlerImpl;
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMovingMongoHandlerImpl;
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
public class MockGPSFixMongoServiceFinder implements TypeBasedServiceFinder<GPSFixMongoHandler> {
private final MongoObjectFactoryImpl mof = new MongoObjectFactoryImpl(null);
private final DomainObjectFactoryImpl dof = new DomainObjectFactoryImpl(null, null);
@Override
public GPSFixMongoHandler findService(String fixType) {
if (fixType.equals(GPSFixMovingImpl.class.getName())) return new GPSFixMovingMongoHandlerImpl(mof, dof);
if (fixType.equals(GPSFixImpl.class.getName())) return new GPSFixMongoHandlerImpl(mof, dof);
return null;
}
@Override
public void setFallbackService(GPSFixMongoHandler fallback) {
}
}
@@ -0,0 +1,28 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
/**
* A simplified implementation of the {@link TypeBasedServiceFinder} interface that, when the device type
* {@link SmartphoneImeiIdentifier#TYPE} is requested, returns a specific handler that was passed to this object's
* constructor.
*
* @author Fredrik Teschke
*
*/
public class MockSmartphoneImeiJsonServiceFinder implements TypeBasedServiceFinder<DeviceIdentifierJsonHandler> {
private final SmartphoneImeiJsonHandler handler = new SmartphoneImeiJsonHandler();
private DeviceIdentifierJsonHandler fallback;
@Override
public DeviceIdentifierJsonHandler findService(String deviceType) {
if (deviceType.equals(SmartphoneImeiIdentifier.TYPE)) return handler;
return fallback;
}
@Override
public void setFallbackService(DeviceIdentifierJsonHandler fallback) {
this.fallback = fallback;
}
}
@@ -0,0 +1,28 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
/**
* A simplified implementation of the {@link TypeBasedServiceFinder} interface that, when the device type
* {@link SmartphoneImeiIdentifier#TYPE} is requested, returns a specific handler that was passed to this object's
* constructor.
*
* @author Fredrik Teschke
*
*/
public class MockSmartphoneImeiMongoServiceFinder implements TypeBasedServiceFinder<DeviceIdentifierMongoHandler> {
private final SmartphoneImeiMongoHandler handler = new SmartphoneImeiMongoHandler();
private DeviceIdentifierMongoHandler fallback;
@Override
public DeviceIdentifierMongoHandler findService(String deviceType) {
if (deviceType.equals(SmartphoneImeiIdentifier.TYPE)) return handler;
return fallback;
}
@Override
public void setFallbackService(DeviceIdentifierMongoHandler fallback) {
this.fallback = fallback;
}
}
@@ -0,0 +1,36 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import java.util.HashMap;
import java.util.Map;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinder;
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
/**
* A simplified implementation of the {@link TypeBasedServiceFinder} interface that, when the device type
* {@link SmartphoneImeiIdentifier#TYPE} is requested, returns a specific handler that was passed to this object's
* constructor.
*
* @author Fredrik Teschke
*
*/
public class MockSmartphoneImeiServiceFinderFactory implements TypeBasedServiceFinderFactory {
Map<Class<?>, TypeBasedServiceFinder<?>> serviceFinders = new HashMap<Class<?>, TypeBasedServiceFinder<?>>();
public MockSmartphoneImeiServiceFinderFactory() {
serviceFinders.put(DeviceIdentifierMongoHandler.class, new MockSmartphoneImeiMongoServiceFinder());
serviceFinders.put(DeviceIdentifierJsonHandler.class, new MockSmartphoneImeiJsonServiceFinder());
serviceFinders.put(GPSFixMongoHandler.class, new MockGPSFixMongoServiceFinder());
serviceFinders.put(GPSFixJsonHandler.class, new MockGPSFixJsonServiceFinder());
}
@SuppressWarnings("unchecked")
@Override
public <ServiceT> TypeBasedServiceFinder<ServiceT> createServiceFinder(Class<ServiceT> clazz) {
return (TypeBasedServiceFinder<ServiceT>) serviceFinders.get(clazz);
}
}
@@ -0,0 +1,48 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
public class SmartphoneImeiIdentifier implements DeviceIdentifier {
private static final long serialVersionUID = -1830014229310181702L;
public static final String TYPE = "smartphoneImei";
private final String imei;
public SmartphoneImeiIdentifier(String imei) {
this.imei = imei;
}
public String getImei() {
return imei;
}
@Override
public String getIdentifierType() {
return TYPE;
}
@Override
public String toString() {
return "IMEI " + imei;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof SmartphoneImeiIdentifier) {
return ((SmartphoneImeiIdentifier) obj).imei.equals(imei);
}
return false;
}
@Override
public int hashCode() {
return imei.hashCode();
}
@Override
public String getStringRepresentation() {
return imei;
}
}
@@ -0,0 +1,16 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
public class SmartphoneImeiJsonHandler extends SmartphoneImeiSerializationHandler
implements DeviceIdentifierJsonHandler {
@Override
public DeviceIdentifier deserialize(Object serialized, String type, String stringRepresentation)
throws TransformationException {
return deserialize((String) serialized, type, stringRepresentation);
}
}
@@ -0,0 +1,16 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
public class SmartphoneImeiMongoHandler extends SmartphoneImeiSerializationHandler
implements DeviceIdentifierMongoHandler {
@Override
public DeviceIdentifier deserialize(Object serialized, String type, String stringRepresentation)
throws TransformationException {
return deserialize((String) serialized, type, stringRepresentation);
}
}
@@ -0,0 +1,21 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
public class SmartphoneImeiSerializationHandler {
private SmartphoneImeiIdentifier castIdentifier(DeviceIdentifier identifier) throws TransformationException {
if (!(identifier instanceof SmartphoneImeiIdentifier))
throw new TransformationException("Expected a SmartphoneImeiIdentifier, got instead: " + identifier);
return (SmartphoneImeiIdentifier) identifier;
}
public Pair<String, String> serialize(DeviceIdentifier deviceIdentifier) throws TransformationException {
return new Pair<String, String>(SmartphoneImeiIdentifier.TYPE, castIdentifier(deviceIdentifier).getImei());
}
public DeviceIdentifier deserialize(String input, String type, String stringRep) throws TransformationException {
return new SmartphoneImeiIdentifier(stringRep);
}
}
@@ -0,0 +1,8 @@
package com.sap.sailing.domain.racelog.tracking.test.mock;
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifierStringSerializationHandler;
public class SmartphoneImeiStringSerializationHandler extends SmartphoneImeiSerializationHandler
implements DeviceIdentifierStringSerializationHandler {
}
@@ -0,0 +1,7 @@
<?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="output" path="bin"/>
</classpath>
@@ -0,0 +1 @@
bin
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.sap.sailing.domain.racelogtrackingadapter</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:51:40 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
Loaded 100 of 662 files, more files were not shown because too many files have changed in this diff. Show more