mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-25 06:58:39 +00:00
Supposedly final.
- With from master pending. - Merge to master deferred after weekend with three events
This commit is contained in:
@@ -8,6 +8,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.common.impl,
|
||||
com.sap.sailing.domain.common.media,
|
||||
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
|
||||
|
||||
+29
-14
@@ -1,15 +1,16 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.media;
|
||||
package com.sap.sailing.domain.common.media;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
|
||||
/**
|
||||
* See http://my.opera.com/core/blog/2010/03/03/everything-you-need-to-know-about-html5-video-and-audio-2
|
||||
* @author D047974
|
||||
*
|
||||
*/
|
||||
public class MediaTrack implements IsSerializable {
|
||||
public class MediaTrack implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public enum MimeType {
|
||||
|
||||
@@ -56,13 +57,6 @@ public class MediaTrack implements IsSerializable {
|
||||
}
|
||||
}
|
||||
|
||||
public class MediaSection implements IsSerializable {
|
||||
public String title;
|
||||
public long offsetInMillis;
|
||||
public Date startTime;
|
||||
public Date endTime;
|
||||
}
|
||||
|
||||
public String dbId;
|
||||
public String title;
|
||||
public String url;
|
||||
@@ -72,11 +66,9 @@ public class MediaTrack implements IsSerializable {
|
||||
public Status status = Status.UNDEFINED;
|
||||
|
||||
public MediaTrack() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public MediaTrack(String dbId, String title, String url, Date startTime, int durationInMillis, MimeType mimeType) {
|
||||
super();
|
||||
this.dbId = dbId;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
@@ -88,6 +80,14 @@ public class MediaTrack implements IsSerializable {
|
||||
public String toString() {
|
||||
return title + " - " + url + " [" + typeToString() + ']' + startTime + " [" + durationInMillis + status + ']';
|
||||
}
|
||||
|
||||
public Date deriveEndTime() {
|
||||
if (startTime != null) {
|
||||
return new Date(startTime.getTime() + durationInMillis);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String typeToString() {
|
||||
return mimeType == null ? "undefined" : mimeType.toString();
|
||||
@@ -96,5 +96,20 @@ public class MediaTrack implements IsSerializable {
|
||||
public boolean isYoutube() {
|
||||
return (mimeType != null) && MediaSubType.youtube.equals(mimeType.mediaSubType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MediaTrack) {
|
||||
MediaTrack mediaTrack = (MediaTrack) obj;
|
||||
return this.dbId.equals(mediaTrack.dbId);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.dbId == null ? 0 : this.dbId.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
+1
-6
@@ -1,6 +1,5 @@
|
||||
package com.sap.sailing.domain.persistence.media;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -14,11 +13,9 @@ public interface MediaDB {
|
||||
|
||||
String insertMediaTrack(String title, String url, Date startTime, int durationInMillis, String mimeType);
|
||||
|
||||
DBMediaTrack loadMediaTrack(String dbId);
|
||||
|
||||
List<DBMediaTrack> loadAllMediaTracks();
|
||||
|
||||
void deleteMediaTrack(String title);
|
||||
void deleteMediaTrack(String dbId);
|
||||
|
||||
void updateTitle(String dbId, String title);
|
||||
|
||||
@@ -28,6 +25,4 @@ public interface MediaDB {
|
||||
|
||||
void updateDuration(String dbId, int durationInMillis);
|
||||
|
||||
Collection<DBMediaTrack> queryOverlappingMediaTracks(Date rangeStart, Date rangeEnd);
|
||||
|
||||
}
|
||||
|
||||
-50
@@ -1,8 +1,6 @@
|
||||
package com.sap.sailing.domain.persistence.media.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -13,7 +11,6 @@ import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.QueryBuilder;
|
||||
import com.sap.sailing.domain.persistence.media.DBMediaTrack;
|
||||
import com.sap.sailing.domain.persistence.media.MediaDB;
|
||||
|
||||
@@ -63,23 +60,6 @@ public class MediaDBImpl implements MediaDB {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBMediaTrack loadMediaTrack(String dbId) {
|
||||
ObjectId objectId = new ObjectId(dbId);
|
||||
DBCursor cursor = getVideoCollection().find(new BasicDBObject(DbNames.Fields._id.name(), objectId));
|
||||
switch (cursor.count()) {
|
||||
case 0:
|
||||
throw new RuntimeException("Video not found with id: " + dbId);
|
||||
case 1:
|
||||
DBObject dbObject = cursor.next();
|
||||
DBMediaTrack dbMediaTrack = createMediaObjectFromDB(dbObject);
|
||||
return dbMediaTrack;
|
||||
default:
|
||||
throw new RuntimeException("Ambiguous videos not found with id: " + dbId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private DBMediaTrack createMediaObjectFromDB(DBObject dbObject) {
|
||||
String dbId = ((ObjectId) dbObject.get(DbNames.Fields._id.name())).toString();
|
||||
String title = (String) dbObject.get(DbNames.Fields.MEDIA_TITLE.name());
|
||||
@@ -152,34 +132,4 @@ public class MediaDBImpl implements MediaDB {
|
||||
getVideoCollection().update(updateQuery, update);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<DBMediaTrack> queryOverlappingMediaTracks(Date rangeStart, Date rangeEnd) {
|
||||
if ((rangeStart != null) && (rangeEnd != null)) {
|
||||
BasicDBObject startTimeCondition = new BasicDBObject();
|
||||
startTimeCondition.put(DbNames.Fields.STARTTIME.name(), new BasicDBObject("$gt", rangeStart));
|
||||
startTimeCondition.put(DbNames.Fields.STARTTIME.name(), new BasicDBObject("$lt", rangeEnd));
|
||||
BasicDBObject endTimeCondition = new BasicDBObject();
|
||||
|
||||
// Should actually be "AND greater than rangeStart - duration".
|
||||
// However, using values calculated on server side turns out to be a nightmare with mongodb.
|
||||
// Instead do the remaining filtering on client side...
|
||||
endTimeCondition.put(DbNames.Fields.STARTTIME.name(), new BasicDBObject("$lt", rangeStart));
|
||||
|
||||
DBObject query = QueryBuilder.start().or(startTimeCondition, endTimeCondition).get();
|
||||
|
||||
DBCursor cursor = getVideoCollection().find(query).sort(sortByStartTimeAndTitle);
|
||||
|
||||
List<DBMediaTrack> result = new ArrayList<>(cursor.count());
|
||||
while (cursor.hasNext()) {
|
||||
DBMediaTrack resultCandidate = createMediaObjectFromDB(cursor.next());
|
||||
if (resultCandidate.durationInMillis > rangeStart.getTime() - resultCandidate.startTime.getTime()) {
|
||||
result.add(resultCandidate);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
com.sap.sailing.domain.swisstimingreplayadapter
|
||||
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.sap.sailing.gwt.ui.client.shared.media
|
||||
Import-Package: javax.jms;version="1.1.0",
|
||||
javax.servlet;version="2.5.0",
|
||||
javax.servlet.http;version="2.5.0",
|
||||
|
||||
+1
-1
@@ -21,8 +21,8 @@ import com.google.gwt.view.client.DefaultSelectionEventManager;
|
||||
import com.google.gwt.view.client.ListDataProvider;
|
||||
import com.google.gwt.view.client.SelectionModel;
|
||||
import com.google.gwt.view.client.SingleSelectionModel;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog.DialogCallback;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.MediaServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
|
||||
+2
-2
@@ -12,10 +12,10 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack.MimeType;
|
||||
|
||||
public class MediaTrackDialog extends DataEntryDialog<MediaTrack> {
|
||||
|
||||
|
||||
+2
-2
@@ -10,10 +10,10 @@ import com.google.gwt.user.client.ui.TextArea;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack.MimeType;
|
||||
|
||||
public class MediaTrackYoutubeDialog extends DataEntryDialog<MediaTrack> {
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
public interface MediaPlayer {
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import java.util.Collection;
|
||||
import com.google.gwt.user.client.rpc.RemoteService;
|
||||
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
@RemoteServiceRelativePath("media")
|
||||
public interface MediaService extends RemoteService {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import java.util.Collection;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
public interface MediaServiceAsync {
|
||||
|
||||
|
||||
+1
-1
@@ -2,8 +2,8 @@ package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.gwt.ui.client.MediaPlayer;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
|
||||
public abstract class AbstractMediaPlayer implements MediaPlayer {
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package com.sap.sailing.gwt.ui.raceboard;
|
||||
import com.google.gwt.dom.client.AudioElement;
|
||||
import com.google.gwt.dom.client.MediaElement;
|
||||
import com.google.gwt.media.client.Audio;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
public class AudioPlayer extends AbstractMediaPlayer {
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import com.google.gwt.user.client.ui.RadioButton;
|
||||
import com.google.gwt.user.client.ui.UIObject;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
public class MediaSelectionDialog implements CloseHandler<PopupPanel> {
|
||||
|
||||
|
||||
+5
-5
@@ -25,6 +25,9 @@ import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MediaType;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.Status;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.MediaPlayer;
|
||||
import com.sap.sailing.gwt.ui.client.PlayStateListener;
|
||||
@@ -32,9 +35,6 @@ import com.sap.sailing.gwt.ui.client.RaceTimesInfoProviderListener;
|
||||
import com.sap.sailing.gwt.ui.client.TimeListener;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayStates;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack.MediaType;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack.Status;
|
||||
import com.sap.sailing.gwt.ui.raceboard.MediaSelectionDialog.MediaSelectionListener;
|
||||
import com.sap.sailing.gwt.ui.raceboard.PopupWindowPlayer.PopupCloseListener;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
@@ -143,10 +143,10 @@ public class MediaSelector implements RaceTimesInfoProviderListener, PlayStateLi
|
||||
native void addLoadMetadataHandler(MediaElement mediaElement, MediaTrack mediaTrack) /*-{
|
||||
var that = this;
|
||||
mediaElement.addEventListener('loadedmetadata', function() {
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.MediaSelector::loadedmetadata(Lcom/sap/sailing/gwt/ui/client/shared/media/MediaTrack;)(mediaTrack);
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.MediaSelector::loadedmetadata(Lcom/sap/sailing/domain/common/media/MediaTrack;)(mediaTrack);
|
||||
});
|
||||
mediaElement.addEventListener('error', function() {
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.MediaSelector::mediaError(Lcom/sap/sailing/gwt/ui/client/shared/media/MediaTrack;)(mediaTrack);
|
||||
that.@com.sap.sailing.gwt.ui.raceboard.MediaSelector::mediaError(Lcom/sap/sailing/domain/common/media/MediaTrack;)(mediaTrack);
|
||||
});
|
||||
}-*/;
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
public abstract class PopupWindowPlayer extends AbstractMediaPlayer {
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.http.client.URL;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
public class VideoWindowPlayer extends PopupWindowPlayer {
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.http.client.URL;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
|
||||
public class YoutubeWindowPlayer extends PopupWindowPlayer {
|
||||
|
||||
|
||||
+95
-57
@@ -4,23 +4,25 @@ import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.domain.persistence.media.DBMediaTrack;
|
||||
import com.sap.sailing.domain.persistence.media.MediaDB;
|
||||
import com.sap.sailing.domain.persistence.media.MediaDBFactory;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.gwt.ui.client.MediaService;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.operationaltransformation.AddMediaTrackBatchOperation;
|
||||
import com.sap.sailing.server.operationaltransformation.AddMediaTrackOperation;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveMediaTrackOperation;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateMediaTrackOperation;
|
||||
|
||||
public class MediaServiceImpl extends RemoteServiceServlet implements MediaService {
|
||||
|
||||
@@ -31,6 +33,8 @@ public class MediaServiceImpl extends RemoteServiceServlet implements MediaServi
|
||||
private ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
|
||||
|
||||
private static final long serialVersionUID = -8917349579281305977L;
|
||||
|
||||
CountDownLatch initializationProgress = new CountDownLatch(1);
|
||||
|
||||
public MediaServiceImpl() {
|
||||
super();
|
||||
@@ -38,85 +42,119 @@ public class MediaServiceImpl extends RemoteServiceServlet implements MediaServi
|
||||
racingEventServiceTracker = new ServiceTracker<RacingEventService, RacingEventService>(
|
||||
context, RacingEventService.class.getName(), null);
|
||||
racingEventServiceTracker.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MediaTrack> getMediaTracksForRace(RegattaAndRaceIdentifier regattaAndRaceIdentifier) {
|
||||
TrackedRace trackedRace = racingEventServiceTracker.getService().getExistingTrackedRace(regattaAndRaceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
Date raceStart = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace().asDate();
|
||||
Date raceEnd = trackedRace.getEndOfRace() == null ? null : trackedRace.getEndOfRace().asDate();
|
||||
return createMediaTracksFromDB(mediaDB().queryOverlappingMediaTracks(raceStart , raceEnd));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MediaTrack> getAllMediaTracks() {
|
||||
List<DBMediaTrack> allDBMediaTracks = mediaDB().loadAllMediaTracks();
|
||||
Collection<MediaTrack> result = createMediaTracksFromDB(allDBMediaTracks);
|
||||
return result;
|
||||
// try {
|
||||
// Date date = dateFormat.parse("2012-09-15 14:42:10 +0100");
|
||||
// return Arrays
|
||||
// .asList(new MediaTrack[] { new MediaTrack(
|
||||
// MediaType.VIDEO,
|
||||
// "Day 2 Final - 49er Europeans 2012",
|
||||
// "http://localhost:8888/media/HTML5/1809147112001_1842870496001_SAP-Regatta-Day02-Final_libtheora.ogv",
|
||||
// date) });
|
||||
// } catch (ParseException e) {
|
||||
// throw new RuntimeException(e); // just due to annoying date parse error potential
|
||||
// }
|
||||
}
|
||||
|
||||
private Collection<MediaTrack> createMediaTracksFromDB(Collection<DBMediaTrack> allDBMediaTracks) {
|
||||
Collection<MediaTrack> result = new ArrayList<MediaTrack>();
|
||||
for (DBMediaTrack dbMediaTrack : allDBMediaTracks) {
|
||||
MediaTrack mediaTrack = createMediaTrackFromDB(dbMediaTrack);
|
||||
result.add(mediaTrack );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private MediaTrack createMediaTrackFromDB(DBMediaTrack dbMediaTrack) {
|
||||
MimeType mimeType = dbMediaTrack.mimeType != null ? MimeType.valueOf(dbMediaTrack.mimeType) : null;
|
||||
MediaTrack mediaTrack = new MediaTrack(dbMediaTrack.dbId, dbMediaTrack.title, dbMediaTrack.url, dbMediaTrack.startTime, dbMediaTrack.durationInMillis, mimeType);
|
||||
return mediaTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMediaTrack(MediaTrack mediaTrack) {
|
||||
String mimeType = mediaTrack.mimeType != null ? mediaTrack.mimeType.name() : null;
|
||||
mediaDB().insertMediaTrack(mediaTrack.title, mediaTrack.url, mediaTrack.startTime, mediaTrack.durationInMillis, mimeType);
|
||||
startInitializationThread();
|
||||
}
|
||||
|
||||
private MediaDB mediaDB() {
|
||||
return MediaDBFactory.INSTANCE.getDefaultMediaDB();
|
||||
}
|
||||
|
||||
private RacingEventService racingEventService() {
|
||||
return racingEventServiceTracker.getService();
|
||||
}
|
||||
|
||||
private void waitForInitialization() {
|
||||
try {
|
||||
int timeout = 10;
|
||||
TimeUnit timeoutUnit = TimeUnit.SECONDS;
|
||||
if (!initializationProgress.await(timeout, timeoutUnit)) {
|
||||
throw new RuntimeException("Media library initialization timed out: " + timeout + ' ' + timeoutUnit);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void startInitializationThread() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateMediaLibary();
|
||||
initializationProgress.countDown();
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects media track references from the configured sources (mongo DB by default, ftp folder yet to be implemented).
|
||||
* The method is expected to be called initially blocking the API until finished.
|
||||
*
|
||||
* Subsequent calls (assumed to be triggered from the admin console or in scheduled intervals) don't need to block. In that case,
|
||||
* the API will simply serve the current state.
|
||||
*
|
||||
*/
|
||||
private void updateMediaLibary() {
|
||||
Collection<DBMediaTrack> allDBMediaTracks = mediaDB().loadAllMediaTracks();
|
||||
Collection<MediaTrack> allMediaTracks = new ArrayList<MediaTrack>(allDBMediaTracks.size());
|
||||
for (DBMediaTrack dbMediaTrack : allDBMediaTracks) {
|
||||
MediaTrack mediaTrack = createMediaTrackFromDB(dbMediaTrack);
|
||||
allMediaTracks.add(mediaTrack );
|
||||
}
|
||||
racingEventService().apply(new AddMediaTrackBatchOperation(allMediaTracks));
|
||||
}
|
||||
|
||||
private MediaTrack createMediaTrackFromDB(DBMediaTrack dbMediaTrack) {
|
||||
MimeType mimeType = dbMediaTrack.mimeType != null ? MimeType.valueOf(dbMediaTrack.mimeType) : null;
|
||||
MediaTrack mediaTrack = new MediaTrack(dbMediaTrack.dbId, dbMediaTrack.title, dbMediaTrack.url, dbMediaTrack.startTime, dbMediaTrack.durationInMillis, mimeType);
|
||||
return mediaTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MediaTrack> getMediaTracksForRace(RegattaAndRaceIdentifier regattaAndRaceIdentifier) {
|
||||
waitForInitialization();
|
||||
return racingEventService().getMediaTracksForRace(regattaAndRaceIdentifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MediaTrack> getAllMediaTracks() {
|
||||
waitForInitialization();
|
||||
return racingEventService().getAllMediaTracks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMediaTrack(MediaTrack mediaTrack) {
|
||||
if (mediaTrack.dbId != null) {
|
||||
throw new IllegalStateException("Property dbId must be null for newly created media track.");
|
||||
}
|
||||
waitForInitialization();
|
||||
racingEventService().apply(new AddMediaTrackOperation(mediaTrack));
|
||||
String mimeType = mediaTrack.mimeType != null ? mediaTrack.mimeType.name() : null;
|
||||
mediaDB().insertMediaTrack(mediaTrack.title, mediaTrack.url, mediaTrack.startTime, mediaTrack.durationInMillis, mimeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMediaTrack(MediaTrack mediaTrack) {
|
||||
waitForInitialization();
|
||||
racingEventService().apply(new RemoveMediaTrackOperation(mediaTrack));
|
||||
mediaDB().deleteMediaTrack(mediaTrack.dbId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTitle(MediaTrack mediaTrack) {
|
||||
waitForInitialization();
|
||||
racingEventService().apply(new UpdateMediaTrackOperation(mediaTrack));
|
||||
mediaDB().updateTitle(mediaTrack.dbId, mediaTrack.title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUrl(MediaTrack mediaTrack) {
|
||||
waitForInitialization();
|
||||
racingEventService().apply(new UpdateMediaTrackOperation(mediaTrack));
|
||||
mediaDB().updateUrl(mediaTrack.dbId, mediaTrack.url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStartTime(MediaTrack mediaTrack) {
|
||||
waitForInitialization();
|
||||
racingEventService().apply(new UpdateMediaTrackOperation(mediaTrack));
|
||||
mediaDB().updateStartTime(mediaTrack.dbId, mediaTrack.startTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDuration(MediaTrack mediaTrack) {
|
||||
waitForInitialization();
|
||||
racingEventService().apply(new UpdateMediaTrackOperation(mediaTrack));
|
||||
mediaDB().updateDuration(mediaTrack.dbId, mediaTrack.durationInMillis);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-126
@@ -1,7 +1,6 @@
|
||||
package com.sap.sailing.media.persistence.test;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -9,23 +8,18 @@ import org.hamcrest.core.Is;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.domain.persistence.media.DBMediaTrack;
|
||||
import com.sap.sailing.domain.persistence.media.MediaDB;
|
||||
import com.sap.sailing.domain.persistence.media.MediaDBFactory;
|
||||
import com.sap.sailing.gwt.ui.client.shared.media.MediaTrack.MimeType;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
public class TestMediaDB extends AbstractMongoDBTest {
|
||||
|
||||
private static final int FIFTEEN_MINUTES_IN_MILLIS = 15 * 60 * 1000;
|
||||
private static final int THIRTY_MINUTES_IN_MILLIS = 30 * 60 * 1000;
|
||||
private static final int ONE_HOUR_IN_MILLIS = 60 * 60 * 1000;
|
||||
|
||||
// private static final Logger logger = Logger.getLogger(TestCRUDMedia.class.getName());
|
||||
|
||||
public TestMediaDB() throws UnknownHostException, MongoException {
|
||||
super();
|
||||
}
|
||||
@@ -39,18 +33,12 @@ public class TestMediaDB extends AbstractMongoDBTest {
|
||||
int durationInMillis = 23;
|
||||
String mimeType = MimeType.ogv.name();
|
||||
String dbId = mongoDB.insertMediaTrack(videoTitle, url, date, durationInMillis, mimeType);
|
||||
DBMediaTrack videoTrack = mongoDB.loadMediaTrack(dbId);
|
||||
DBMediaTrack videoTrack = mongoDB.loadAllMediaTracks().iterator().next();
|
||||
assertNotNull(videoTrack);
|
||||
assertThat(videoTrack.dbId, Is.is(dbId));
|
||||
assertThat(videoTrack.title, Is.is(videoTitle));
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testFailReadMissingVideoTrack() {
|
||||
final String dbId = "non-existing id";
|
||||
MediaDB mongoDB = MediaDBFactory.INSTANCE.getMediaDB(getMongoService());
|
||||
mongoDB.loadMediaTrack(dbId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllVideoTracks() {
|
||||
MediaDB mongoDB = MediaDBFactory.INSTANCE.getMediaDB(getMongoService());
|
||||
@@ -72,7 +60,7 @@ public class TestMediaDB extends AbstractMongoDBTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=RuntimeException.class)
|
||||
@Test
|
||||
public void testDeleteVideoTrack() {
|
||||
//insert test object
|
||||
final String videoTitle = "Test Video";
|
||||
@@ -84,10 +72,10 @@ public class TestMediaDB extends AbstractMongoDBTest {
|
||||
String dbId = mongoDB.insertMediaTrack(videoTitle, url, date, durationInMillis, mimeType);
|
||||
|
||||
//delete
|
||||
mongoDB.deleteMediaTrack(videoTitle);
|
||||
mongoDB.deleteMediaTrack(dbId);
|
||||
|
||||
//assert not exists --> RuntimeException
|
||||
mongoDB.loadMediaTrack(dbId);
|
||||
assertThat(mongoDB.loadAllMediaTracks().size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,7 +94,7 @@ public class TestMediaDB extends AbstractMongoDBTest {
|
||||
mongoDB.updateStartTime(dbId, newDate);
|
||||
|
||||
//assert start time is updated and everything else preserved
|
||||
DBMediaTrack videoTrack = mongoDB.loadMediaTrack(dbId);
|
||||
DBMediaTrack videoTrack = mongoDB.loadAllMediaTracks().iterator().next();
|
||||
assertThat(videoTrack.startTime, is(newDate));
|
||||
assertThat(videoTrack.durationInMillis, is(durationInMillis));
|
||||
assertThat(videoTrack.title, is(videoTitle));
|
||||
@@ -114,110 +102,4 @@ public class TestMediaDB extends AbstractMongoDBTest {
|
||||
assertThat(videoTrack.mimeType, is(mimeType));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_MatchingStartTimes_TrackLongerThanEndTime() {
|
||||
Date startTime = new Date();
|
||||
int duration = ONE_HOUR_IN_MILLIS;
|
||||
Date rangeStart = startTime;
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_MatchingStartTimes_TrackShorterThanEndTime() {
|
||||
Date startTime = new Date();
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
Date rangeStart = startTime;
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsBeforeEndsAfterRange() {
|
||||
Date startTime = new Date();
|
||||
int duration = ONE_HOUR_IN_MILLIS;
|
||||
Date rangeStart = new Date(startTime.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsAfterEndsBeforeRange() {
|
||||
Date rangeStart = new Date();
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
Date startTime = new Date(rangeStart.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
int duration = FIFTEEN_MINUTES_IN_MILLIS;
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsAfterEndsAfterRange() {
|
||||
Date rangeStart = new Date();
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
Date startTime = new Date(rangeStart.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsBeforeEndsBeforeRange() {
|
||||
Date startTime = new Date();
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
Date rangeStart = new Date(startTime.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_TrackEndsBeforeRange() {
|
||||
Date startTime = new Date();
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
Date rangeStart = new Date(startTime.getTime() + duration + 1);
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
|
||||
assertNoOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_TrackStartsAfterRange() {
|
||||
Date rangeStart = new Date();
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
Date startTime = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
|
||||
assertNoOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
private void assertOverlap(Date startTime, int oneHourInMillis, Date rangeStart, Date rangeEnd) {
|
||||
//insert test object
|
||||
final String videoTitle = "Test Video";
|
||||
final String url = "test";
|
||||
MediaDB mongoDB = MediaDBFactory.INSTANCE.getMediaDB(getMongoService());
|
||||
String mimeType = MimeType.ogv.name();
|
||||
String dbId = mongoDB.insertMediaTrack(videoTitle, url, startTime, oneHourInMillis, mimeType);
|
||||
|
||||
Collection<DBMediaTrack> videoTracks = mongoDB.queryOverlappingMediaTracks(rangeStart, rangeEnd);
|
||||
assertThat(videoTracks.size(), is(1));
|
||||
assertThat(videoTracks.iterator().next().dbId, is(dbId));
|
||||
}
|
||||
|
||||
private void assertNoOverlap(Date startTime, int oneHourInMillis, Date rangeStart, Date rangeEnd) {
|
||||
//insert test object
|
||||
final String videoTitle = "Test Video";
|
||||
final String url = "test";
|
||||
MediaDB mongoDB = MediaDBFactory.INSTANCE.getMediaDB(getMongoService());
|
||||
String mimeType = MimeType.ogv.name();
|
||||
mongoDB.insertMediaTrack(videoTitle, url, startTime, oneHourInMillis, mimeType);
|
||||
|
||||
Collection<DBMediaTrack> videoTracks = mongoDB.queryOverlappingMediaTracks(rangeStart, rangeEnd);
|
||||
assertThat(videoTracks.size(), is(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,4 +20,5 @@ Require-Bundle: com.sap.sailing.server,
|
||||
com.tractrac.clientmodule;bundle-version="2.0.0",
|
||||
com.sap.sailing.expeditionconnector,
|
||||
com.sap.sailing.domain.swisstimingadapter,
|
||||
org.json.simple;bundle-version="1.1.0"
|
||||
org.json.simple;bundle-version="1.1.0",
|
||||
org.hamcrest;bundle-version="1.1.0"
|
||||
|
||||
+14
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -25,6 +26,8 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
import com.sap.sailing.domain.common.RegattaName;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||
import com.sap.sailing.domain.test.TrackBasedTest;
|
||||
import com.sap.sailing.mongodb.MongoDBService;
|
||||
@@ -99,6 +102,16 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl
|
||||
assertNotNull(master.getLeaderboardGroupByName(leaderBoardGroupName));
|
||||
assertNull(replica.getLeaderboardGroupByName(leaderBoardGroupName));
|
||||
|
||||
/* Media Library */
|
||||
String dbId = "1234";
|
||||
String title = "title";
|
||||
String url = "url";
|
||||
Date startTime = new Date();
|
||||
int durationInMillis = 1;
|
||||
MimeType mimeType = MimeType.mp4;
|
||||
MediaTrack mediaTrack = new MediaTrack(dbId, title, url, startTime, durationInMillis, mimeType);
|
||||
master.mediaTrackAdded(mediaTrack);
|
||||
|
||||
/* fire up replication */
|
||||
performReplicationSetup();
|
||||
ReplicationMasterDescriptor the_master = replicationDescriptorPair.getB(); /* master descriptor */
|
||||
@@ -116,6 +129,7 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl
|
||||
assertNotNull(replica.getLeaderboardGroupByName(leaderBoardGroupName));
|
||||
assertNotNull(replica.getLeaderboardByName(leaderboardName));
|
||||
assertTrue(replica.getAllRegattas().iterator().hasNext());
|
||||
assertTrue(replica.getAllMediaTracks().iterator().hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
package com.sap.sailing.server.replication.test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.server.operationaltransformation.AddMediaTrackBatchOperation;
|
||||
import com.sap.sailing.server.operationaltransformation.AddMediaTrackOperation;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveMediaTrackOperation;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateMediaTrackOperation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
public class MediaReplicationTest extends AbstractServerReplicationTest {
|
||||
|
||||
/* util */
|
||||
private MediaTrack createMediaTrack(String dbId) {
|
||||
String title = "title";
|
||||
String url = "url";
|
||||
Date startTime = new Date();
|
||||
int durationInMillis = 1;
|
||||
MimeType mimeType = MimeType.mp4;
|
||||
MediaTrack mediaTrack = new MediaTrack(dbId, title, url, startTime, durationInMillis, mimeType);
|
||||
return mediaTrack;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicInitialLoad() throws Exception {
|
||||
assertNotSame(master, replica);
|
||||
assertEquals(master.getAllMediaTracks().size(), replica.getAllMediaTracks().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddMediaTrackReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack = createMediaTrack("1");
|
||||
AddMediaTrackOperation addMediaTrackOperation = new AddMediaTrackOperation(mediaTrack);
|
||||
assertThat(master.getAllMediaTracks().size(), is(0));
|
||||
assertThat(replica.getAllMediaTracks().size(), is(0));
|
||||
master.apply(addMediaTrackOperation);
|
||||
assertThat(master.getAllMediaTracks().size(), is(1));
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().size(), is(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMediaTrackReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack = createMediaTrack("1");
|
||||
AddMediaTrackOperation addMediaTrackOperation = new AddMediaTrackOperation(mediaTrack);
|
||||
master.apply(addMediaTrackOperation);
|
||||
RemoveMediaTrackOperation removeMediaTrackOperation = new RemoveMediaTrackOperation(mediaTrack);
|
||||
master.apply(removeMediaTrackOperation);
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testaddMediaTrackBatchReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack1 = createMediaTrack("1");
|
||||
MediaTrack mediaTrack2 = createMediaTrack("2");
|
||||
Collection<MediaTrack> mediaTrackBatch = Arrays.asList(new MediaTrack[] {mediaTrack1, mediaTrack2});
|
||||
AddMediaTrackBatchOperation addMediaTrackBatchOperation = new AddMediaTrackBatchOperation(mediaTrackBatch);
|
||||
master.apply(addMediaTrackBatchOperation);
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().size(), is(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMediaTrackTitleReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack = createMediaTrack("1");
|
||||
AddMediaTrackOperation addMediaTrackOperation = new AddMediaTrackOperation(mediaTrack);
|
||||
master.apply(addMediaTrackOperation);
|
||||
mediaTrack.title = mediaTrack.title + "x";
|
||||
UpdateMediaTrackOperation updateMediaTrackOperation = new UpdateMediaTrackOperation(mediaTrack);
|
||||
master.apply(updateMediaTrackOperation);
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().iterator().next().title, is(mediaTrack.title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMediaTrackUrlReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack = createMediaTrack("1");
|
||||
AddMediaTrackOperation addMediaTrackOperation = new AddMediaTrackOperation(mediaTrack);
|
||||
master.apply(addMediaTrackOperation);
|
||||
mediaTrack.url = mediaTrack.url + "x";
|
||||
UpdateMediaTrackOperation updateMediaTrackOperation = new UpdateMediaTrackOperation(mediaTrack);
|
||||
master.apply(updateMediaTrackOperation);
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().iterator().next().url, is(mediaTrack.url));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMediaTrackStartTimeReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack = createMediaTrack("1");
|
||||
AddMediaTrackOperation addMediaTrackOperation = new AddMediaTrackOperation(mediaTrack);
|
||||
master.apply(addMediaTrackOperation);
|
||||
mediaTrack.startTime = new Date(mediaTrack.startTime.getTime() + 1000);
|
||||
UpdateMediaTrackOperation updateMediaTrackOperation = new UpdateMediaTrackOperation(mediaTrack);
|
||||
master.apply(updateMediaTrackOperation);
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().iterator().next().startTime, is(mediaTrack.startTime));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMediaTrackDurationReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack = createMediaTrack("1");
|
||||
AddMediaTrackOperation addMediaTrackOperation = new AddMediaTrackOperation(mediaTrack);
|
||||
master.apply(addMediaTrackOperation);
|
||||
mediaTrack.durationInMillis = mediaTrack.durationInMillis + 1000;
|
||||
UpdateMediaTrackOperation updateMediaTrackOperation = new UpdateMediaTrackOperation(mediaTrack);
|
||||
master.apply(updateMediaTrackOperation);
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().iterator().next().durationInMillis, is(mediaTrack.durationInMillis));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMediaTrackMimeTypeReplication() throws InterruptedException {
|
||||
MediaTrack mediaTrack = createMediaTrack("1");
|
||||
AddMediaTrackOperation addMediaTrackOperation = new AddMediaTrackOperation(mediaTrack);
|
||||
master.apply(addMediaTrackOperation);
|
||||
mediaTrack.mimeType = MimeType.mp3;
|
||||
UpdateMediaTrackOperation updateMediaTrackOperation = new UpdateMediaTrackOperation(mediaTrack);
|
||||
master.apply(updateMediaTrackOperation);
|
||||
Thread.sleep(500); // wait for JMS to deliver the message and the message to be applied
|
||||
assertThat(replica.getAllMediaTracks().iterator().next().mimeType, is(mediaTrack.mimeType));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,9 +15,9 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
com.sap.sailing.mongodb,
|
||||
com.tractrac.clientmodule;bundle-version="2.0.0",
|
||||
com.mongodb.driver;bundle-version="2.6.2",
|
||||
com.sap.sailing.domain.test
|
||||
com.sap.sailing.domain.test,
|
||||
org.hamcrest;bundle-version="1.1.0"
|
||||
Import-Package: junit.framework;version="4.8.1",
|
||||
org.junit;version="4.8.1",
|
||||
org.json.simple
|
||||
Export-Package: com.sap.sailing.server,
|
||||
com.sap.sailing.server.impl
|
||||
Export-Package: com.sap.sailing.server.impl
|
||||
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
package com.sap.sailing.server.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack.MimeType;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
import com.sap.sailing.server.Replicator;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
|
||||
public class MediaLibaryTest {
|
||||
|
||||
private static final int FIFTEEN_MINUTES_IN_MILLIS = 15 * 60 * 1000;
|
||||
private static final int THIRTY_MINUTES_IN_MILLIS = 30 * 60 * 1000;
|
||||
private static final int ONE_HOUR_IN_MILLIS = 60 * 60 * 1000;
|
||||
|
||||
private MediaLibrary mediaLibary;
|
||||
private Replicator replicator;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
replicator = new Replicator() {
|
||||
|
||||
@Override
|
||||
public <T> void replicate(RacingEventServiceOperation<T> operation) {
|
||||
}
|
||||
|
||||
};
|
||||
this.mediaLibary = new MediaLibrary(replicator);
|
||||
}
|
||||
|
||||
/* util */
|
||||
private MediaTrack createMediaTrack(String dbId) {
|
||||
String title = "title";
|
||||
String url = "url";
|
||||
Date startTime = new Date();
|
||||
int durationInMillis = 1;
|
||||
MimeType mimeType = MimeType.mp4;
|
||||
MediaTrack mediaTrack = new MediaTrack(dbId, title, url, startTime, durationInMillis, mimeType);
|
||||
return mediaTrack;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetElementsFromEmtpy() throws Exception {
|
||||
assertThat(this.mediaLibary.allTracks().size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateOneElement() throws Exception {
|
||||
String dbId = "1234";
|
||||
MediaTrack mediaTrack = createMediaTrack(dbId);
|
||||
this.mediaLibary.addMediaTrack(mediaTrack);
|
||||
Iterator<MediaTrack> allMediaTracks = this.mediaLibary.allTracks().iterator();
|
||||
assertThat(allMediaTracks.hasNext(), is(true));
|
||||
MediaTrack item = allMediaTracks.next();
|
||||
assertThat(allMediaTracks.hasNext(), is(false));
|
||||
assertTrue(item.equals(mediaTrack));
|
||||
assertThat(item.title, is(mediaTrack.title));
|
||||
assertThat(item.url, is(mediaTrack.url));
|
||||
assertThat(item.startTime, is(mediaTrack.startTime));
|
||||
assertThat(item.durationInMillis, is(mediaTrack.durationInMillis));
|
||||
assertThat(item.mimeType, is(mediaTrack.mimeType));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDeleteOneElement() throws Exception {
|
||||
String dbId = "1234";
|
||||
MediaTrack mediaTrack = createMediaTrack(dbId);
|
||||
this.mediaLibary.addMediaTrack(mediaTrack);
|
||||
this.mediaLibary.deleteMediaTrack(mediaTrack);
|
||||
Collection<MediaTrack> allMediaTracks = this.mediaLibary.allTracks();
|
||||
assertThat(allMediaTracks.size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_MatchingStartTimes_TrackLongerThanEndTime() {
|
||||
Date startTime = new Date();
|
||||
int duration = ONE_HOUR_IN_MILLIS;
|
||||
Date rangeStart = startTime;
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_MatchingStartTimes_TrackShorterThanEndTime() {
|
||||
Date startTime = new Date();
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
Date rangeStart = startTime;
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsBeforeEndsAfterRange() {
|
||||
Date startTime = new Date();
|
||||
int duration = ONE_HOUR_IN_MILLIS;
|
||||
Date rangeStart = new Date(startTime.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsAfterEndsBeforeRange() {
|
||||
Date rangeStart = new Date();
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
Date startTime = new Date(rangeStart.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
int duration = FIFTEEN_MINUTES_IN_MILLIS;
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsAfterEndsAfterRange() {
|
||||
Date rangeStart = new Date();
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
Date startTime = new Date(rangeStart.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_StartsBeforeEndsBeforeRange() {
|
||||
Date startTime = new Date();
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
Date rangeStart = new Date(startTime.getTime() + FIFTEEN_MINUTES_IN_MILLIS);
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
|
||||
assertOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_TrackEndsBeforeRange() {
|
||||
Date startTime = new Date();
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
Date rangeStart = new Date(startTime.getTime() + duration + 1);
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
|
||||
assertNoOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryMediaTracksBetween_TrackStartsAfterRange() {
|
||||
Date rangeStart = new Date();
|
||||
Date rangeEnd = new Date(rangeStart.getTime() + THIRTY_MINUTES_IN_MILLIS);
|
||||
Date startTime = new Date(rangeStart.getTime() + ONE_HOUR_IN_MILLIS);
|
||||
int duration = THIRTY_MINUTES_IN_MILLIS;
|
||||
|
||||
assertNoOverlap(startTime, duration, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
private void assertOverlap(Date startTime, int durationInMillis, Date rangeStart, Date rangeEnd) {
|
||||
//insert test object
|
||||
String dbId = "1234";
|
||||
String title = "title";
|
||||
String url = "url";
|
||||
MimeType mimeType = MimeType.mp4;
|
||||
MediaTrack mediaTrack = new MediaTrack(dbId, title, url, startTime, durationInMillis, mimeType);
|
||||
mediaLibary.addMediaTrack(mediaTrack);
|
||||
|
||||
Collection<MediaTrack> mediaTracks = mediaLibary.findMediaTracksInTimeRange(rangeStart, rangeEnd);
|
||||
assertThat(mediaTracks.size(), is(1));
|
||||
assertThat(mediaTracks.iterator().next().dbId, is(dbId));
|
||||
}
|
||||
|
||||
private void assertNoOverlap(Date startTime, int durationInMillis, Date rangeStart, Date rangeEnd) {
|
||||
//insert test object
|
||||
String dbId = "1234";
|
||||
String title = "title";
|
||||
String url = "url";
|
||||
MimeType mimeType = MimeType.mp4;
|
||||
MediaTrack mediaTrack = new MediaTrack(dbId, title, url, startTime, durationInMillis, mimeType);
|
||||
mediaLibary.addMediaTrack(mediaTrack);
|
||||
|
||||
Collection<MediaTrack> mediaTracks = mediaLibary.findMediaTracksInTimeRange(rangeStart, rangeEnd);
|
||||
assertThat(mediaTracks.size(), is(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,11 +12,11 @@ import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
@@ -501,4 +502,16 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
|
||||
CourseArea getCourseArea(Serializable courseAreaId);
|
||||
|
||||
void mediaTrackAdded(MediaTrack mediaTrack);
|
||||
|
||||
void mediaTracksAdded(Collection<MediaTrack> mediaTracks);
|
||||
|
||||
void mediaTrackChanged(MediaTrack mediaTrack);
|
||||
|
||||
void mediaTrackDeleted(MediaTrack mediaTrack);
|
||||
|
||||
Collection<MediaTrack> getMediaTracksForRace(RegattaAndRaceIdentifier regattaAndRaceIdentifier);
|
||||
|
||||
Collection<MediaTrack> getAllMediaTracks();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.sap.sailing.server.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.server.Replicator;
|
||||
|
||||
class MediaLibrary {
|
||||
|
||||
/* public class MediaTrack{
|
||||
|
||||
MediaItem(boolean isMutable) {
|
||||
this.isMutable = isMutable;
|
||||
}
|
||||
|
||||
public final boolean isMutable;
|
||||
public String id;
|
||||
public String title;
|
||||
public String url;
|
||||
public Date startTime;
|
||||
public int durationInMillis;
|
||||
public String mimeType;
|
||||
}*/
|
||||
|
||||
private List<MediaTrack> mediaTracks;
|
||||
|
||||
MediaLibrary(Replicator replicator) {
|
||||
this.mediaTracks = new CopyOnWriteArrayList<MediaTrack>();
|
||||
}
|
||||
|
||||
Collection<MediaTrack> findMediaTracksInTimeRange(Date startTime, Date endTime) {
|
||||
Collection<MediaTrack> result = new ArrayList<MediaTrack>();
|
||||
for (MediaTrack mediaTrack : mediaTracks) {
|
||||
long mediaStartTime = mediaTrack.startTime.getTime();
|
||||
long mediaEndTime = mediaStartTime + mediaTrack.durationInMillis;
|
||||
if (startTime.getTime() < mediaEndTime && mediaStartTime < endTime.getTime()) {
|
||||
result.add(mediaTrack);
|
||||
}
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
void addMediaTrack(MediaTrack mediaTrack) {
|
||||
mediaTracks.add(mediaTrack);
|
||||
}
|
||||
|
||||
void addMediaTracks(Collection<MediaTrack> mediaTracks) {
|
||||
this.mediaTracks.addAll(mediaTracks);
|
||||
}
|
||||
|
||||
void deleteMediaTrack(MediaTrack mediaTrack) {
|
||||
mediaTracks.remove(mediaTrack);
|
||||
}
|
||||
|
||||
void applyChanges(MediaTrack changedMediaTrack) {
|
||||
for (MediaTrack mediaTrack : mediaTracks) {
|
||||
if (mediaTrack.equals(changedMediaTrack)) {
|
||||
mediaTrack.title = changedMediaTrack.title;
|
||||
mediaTrack.url = changedMediaTrack.url;
|
||||
mediaTrack.startTime = changedMediaTrack.startTime;
|
||||
mediaTrack.durationInMillis = changedMediaTrack.durationInMillis;
|
||||
mediaTrack.mimeType = changedMediaTrack.mimeType;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collection<MediaTrack> allTracks() {
|
||||
return new ArrayList<MediaTrack>(mediaTracks);
|
||||
}
|
||||
|
||||
void serialize(ObjectOutputStream stream) throws IOException {
|
||||
stream.writeObject(mediaTracks);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void deserialize(ObjectInputStream stream) throws ClassNotFoundException, IOException {
|
||||
addMediaTracks((Collection<MediaTrack>) stream.readObject());
|
||||
}
|
||||
|
||||
}
|
||||
+47
-1
@@ -12,7 +12,9 @@ import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -27,7 +29,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
@@ -56,6 +57,7 @@ import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleRaceColumn;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
@@ -203,6 +205,8 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
|
||||
|
||||
private final RaceLogScoringReplicator raceLogScoringReplicator;
|
||||
|
||||
private MediaLibrary mediaLibrary;
|
||||
|
||||
public RacingEventServiceImpl() {
|
||||
this(MongoFactory.INSTANCE.getDefaultDomainObjectFactory(), MongoFactory.INSTANCE.getDefaultMongoObjectFactory());
|
||||
}
|
||||
@@ -241,6 +245,7 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
|
||||
delayToLiveInMillis = TrackedRace.DEFAULT_LIVE_DELAY_IN_MILLISECONDS;
|
||||
this.raceLogReplicator = new RaceLogReplicator(this);
|
||||
this.raceLogScoringReplicator = new RaceLogScoringReplicator(this);
|
||||
this.mediaLibrary = new MediaLibrary(this);
|
||||
|
||||
// Add one default leaderboard that aggregates all races currently tracked by this service.
|
||||
// This is more for debugging purposes than for anything else.
|
||||
@@ -1598,6 +1603,8 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
|
||||
oos.writeObject(leaderboardGroupsByName);
|
||||
logger.info("serializing leaderboardsByName");
|
||||
oos.writeObject(leaderboardsByName);
|
||||
logger.info("serializing mediaLibrary");
|
||||
mediaLibrary.serialize(oos);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // the type-parameters in the casts of the de-serialized collection objects can't be checked
|
||||
@@ -1649,6 +1656,8 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
|
||||
((LeaderboardGroupMetaLeaderboard) leaderboard).registerAsScoreCorrectionChangeForwarderAndRaceColumnListenerOnAllLeaderboards();
|
||||
}
|
||||
}
|
||||
logger.info("receiving mediaLibrary");
|
||||
mediaLibrary.deserialize(ois);
|
||||
logger.info("Done with initial replication on "+this);
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(oldContextClassloader);
|
||||
@@ -1756,4 +1765,41 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
|
||||
return courseArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mediaTrackAdded(MediaTrack mediaTrack) {
|
||||
mediaLibrary.addMediaTrack(mediaTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mediaTracksAdded(Collection<MediaTrack> mediaTracks) {
|
||||
mediaLibrary.addMediaTracks(mediaTracks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mediaTrackChanged(MediaTrack mediaTrack) {
|
||||
mediaLibrary.applyChanges(mediaTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mediaTrackDeleted(MediaTrack mediaTrack) {
|
||||
mediaLibrary.deleteMediaTrack(mediaTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MediaTrack> getMediaTracksForRace(RegattaAndRaceIdentifier regattaAndRaceIdentifier) {
|
||||
TrackedRace trackedRace = getExistingTrackedRace(regattaAndRaceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
Date raceStart = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace().asDate();
|
||||
Date raceEnd = trackedRace.getEndOfRace() == null ? null : trackedRace.getEndOfRace().asDate();
|
||||
return mediaLibrary.findMediaTracksInTimeRange(raceStart , raceEnd);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MediaTrack> getAllMediaTracks() {
|
||||
return mediaLibrary.allTracks();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
public abstract class AbstractMediaTrackOperation extends AbstractRacingEventServiceOperation<Void> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected final MediaTrack mediaTrack;
|
||||
|
||||
public AbstractMediaTrackOperation(MediaTrack mediaTrack) {
|
||||
this.mediaTrack = mediaTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
public class AddMediaTrackBatchOperation extends AbstractRacingEventServiceOperation<Void> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Collection<MediaTrack> mediaTracks;
|
||||
|
||||
public AddMediaTrackBatchOperation(Collection<MediaTrack> mediaTracks) {
|
||||
this.mediaTracks = mediaTracks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalApplyTo(RacingEventService toState) throws Exception {
|
||||
toState.mediaTracksAdded(this.mediaTracks);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
|
||||
return null; //no op
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
|
||||
return null; //no op
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class AddMediaTrackOperation extends AbstractMediaTrackOperation {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AddMediaTrackOperation(MediaTrack mediaTrack) {
|
||||
super(mediaTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalApplyTo(RacingEventService toState) throws Exception {
|
||||
toState.mediaTrackAdded(this.mediaTrack);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class RemoveMediaTrackOperation extends AbstractMediaTrackOperation {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public RemoveMediaTrackOperation(MediaTrack mediaTrack) {
|
||||
super(mediaTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalApplyTo(RacingEventService toState) throws Exception {
|
||||
toState.mediaTrackDeleted(this.mediaTrack);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class UpdateMediaTrackOperation extends AbstractMediaTrackOperation {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UpdateMediaTrackOperation(MediaTrack mediaTrack) {
|
||||
super(mediaTrack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalApplyTo(RacingEventService toState) throws Exception {
|
||||
toState.mediaTrackChanged(this.mediaTrack);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user