Revert "added racelog editing to AdminConsole"

This reverts commit 7d00664ae6.

Conflicts:
	java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLog.java
	java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/NoAddingRaceLogWrapper.java
	java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogImpl.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java
This commit is contained in:
Fredrik Teschke committed 2014-02-26 14:48:35 +01:00
1 parent ab94e53fc7
commit 7132a31d34
24 files changed
+4359 -4705

No files matched your search

@@ -9,7 +9,7 @@ public class TransformationException extends IOException {
}
public TransformationException(Class<?> from, Class<?> to, String at, Throwable e) {
super("Couldn't transform " +from.getName()+" into "+to.getName()+" at "+at, e);
super(String.format("Couldn't transform %s into %s at %s", from.getName(), to.getName(), at), e);
}
public TransformationException(Class<?> from, Class<?> to, String at) {
@@ -14,8 +14,6 @@ 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.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
@@ -109,9 +107,4 @@ public interface MongoObjectFactory {
void storeDeviceConfiguration(DeviceConfigurationMatcher matcher, DeviceConfiguration configuration);
void removeDeviceConfiguration(DeviceConfigurationMatcher matcher);
/**
* Rewrite entire racelog to DB after changes. This deletes old events, and updates changes ones.
*/
void rewriteRaceLog(RaceLogIdentifier identifier, RaceLog raceLog);
}
@@ -62,7 +62,6 @@ import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogCourseAreaChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogEvent;
@@ -1132,21 +1131,4 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
.add(FieldNames.DEVICE_TYPE.name(), device.getIdentifierType())
.add(FieldNames.DEVICE_TYPE_ID.name(), deviceTypeId).get();
}
@Override
public void rewriteRaceLog(RaceLogIdentifier identifier, RaceLog raceLog) {
DBObject query = new BasicDBObject(FieldNames.RACE_LOG_IDENTIFIER.name(),
TripleSerializer.serialize(identifier.getIdentifier()));
getRaceLogCollection().remove(query);
MongoRaceLogStoreVisitor visitor = new MongoRaceLogStoreVisitor(identifier, this);
raceLog.lockForRead();
try {
for (RaceLogEvent event : raceLog.getRawFixes()) {
event.accept(visitor);
}
} finally {
raceLog.unlockAfterRead();
}
}
}
@@ -79,8 +79,6 @@ public class RaceLogEventComparatorTest {
when(eventTwo.getPassId()).thenReturn(0);
when(eventTwo.getAuthor()).thenReturn(author);
when(eventTwo.getCreatedAt()).thenReturn(new MillisecondsTimePoint(2));
when(eventOne.getId()).thenReturn("a");
when(eventTwo.getId()).thenReturn("b");
int result = comparator.compare(eventOne, eventTwo);
assertTrue(result < 0);
@@ -94,8 +92,6 @@ public class RaceLogEventComparatorTest {
when(eventTwo.getPassId()).thenReturn(0);
when(eventTwo.getAuthor()).thenReturn(author);
when(eventTwo.getCreatedAt()).thenReturn(new MillisecondsTimePoint(1));
when(eventOne.getId()).thenReturn("a");
when(eventTwo.getId()).thenReturn("b");
int result = comparator.compare(eventOne, eventTwo);
assertTrue(result > 0);
@@ -112,8 +108,6 @@ public class RaceLogEventComparatorTest {
when(eventOne.getAuthor()).thenReturn(minorAuthor);
when(eventTwo.getPassId()).thenReturn(0);
when(eventTwo.getAuthor()).thenReturn(majorAuthor);
when(eventOne.getId()).thenReturn("a");
when(eventTwo.getId()).thenReturn("b");
int result = comparator.compare(eventOne, eventTwo);
assertTrue(result < 0);
@@ -130,8 +124,6 @@ public class RaceLogEventComparatorTest {
when(eventOne.getAuthor()).thenReturn(majorAuthor);
when(eventTwo.getPassId()).thenReturn(0);
when(eventTwo.getAuthor()).thenReturn(minorAuthor);
when(eventOne.getId()).thenReturn("a");
when(eventTwo.getId()).thenReturn("b");
int result = comparator.compare(eventOne, eventTwo);
assertTrue(result > 0);
@@ -143,8 +135,6 @@ public class RaceLogEventComparatorTest {
when(eventOne.getCreatedAt()).thenReturn(new MillisecondsTimePoint(2));
when(eventTwo.getPassId()).thenReturn(1);
when(eventTwo.getCreatedAt()).thenReturn(new MillisecondsTimePoint(1));
when(eventOne.getId()).thenReturn("a");
when(eventTwo.getId()).thenReturn("b");
int result = comparator.compare(eventOne, eventTwo);
assertTrue(result < 0);
@@ -156,8 +146,6 @@ public class RaceLogEventComparatorTest {
when(eventOne.getCreatedAt()).thenReturn(new MillisecondsTimePoint(1));
when(eventTwo.getPassId()).thenReturn(0);
when(eventTwo.getCreatedAt()).thenReturn(new MillisecondsTimePoint(2));
when(eventOne.getId()).thenReturn("a");
when(eventTwo.getId()).thenReturn("b");
int result = comparator.compare(eventOne, eventTwo);
assertTrue(result > 0);
@@ -1,143 +1,132 @@
package com.sap.sailing.domain.racelog;
import java.io.Serializable;
import java.util.HashSet;
import java.util.NavigableSet;
import java.util.UUID;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.racelog.impl.RaceLogEventComparator;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Track;
/**
* Special kind of {@link Track} for recording {@link RaceLogEvent}s.
*
* <p>
* Keeps track of the {@link RaceLogEvent}'s pass and returns only the events of the current pass on
* {@link RaceLog#getFixes()}. Use {@link RaceLog#getRawFixes()} to receive all events in a {@link RaceLog}.
* </p>
*
* <p>
* Implementations should use the {@link RaceLogEventComparator} for sorting its content.
* </p>
*/
public interface RaceLog extends Track<RaceLogEvent>, WithID {
public static final int DefaultPassId = 0;
/**
* Gets the current pass id.
*
* @return the pass id.
*/
int getCurrentPassId();
/**
* Adds a {@link RaceLogEvent} to the {@link RaceLog}.
*
* @param event
* {@link RaceLogEvent} to be added.
* @return <code>true</code> if the element was added, <code>false</code> otherwise.
*/
boolean add(RaceLogEvent event);
/**
* Add a {@link RaceLogEventVisitor} as a listener for additions.
*/
void addListener(RaceLogEventVisitor listener);
/**
* Remove a listener.
*/
void removeListener(RaceLogEventVisitor listener);
/**
* Removes all listeners
* @return
*/
HashSet<RaceLogEventVisitor> removeAllListeners();
/**
* Checks if the race log is empty.
*/
boolean isEmpty();
Iterable<RaceLogEvent> getRawFixesDescending();
Iterable<RaceLogEvent> getFixesDescending();
void addAllListeners(HashSet<RaceLogEventVisitor> listeners);
Iterable<RaceLogEventVisitor> getAllListeners();
/**
* Adds an event to this race log and returns {@link RaceLog#getEventsToDeliver(UUID)}
* (excluding the new <code>event</code>)
*/
Iterable<RaceLogEvent> add(RaceLogEvent event, UUID clientId);
/**
* Returns a superset of all race log events that were added to this race log but not yet returned to
* the client with ID <code>clientId</code> by this method. In general, the list returned is not a true
* superset but equals exactly those events not yet delivered to the client. However, if the server
* was re-started since the client last called this method, and since the underlying data structures
* are not durably stored, the entire set of all race log events would be delivered to the client once.
*/
Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId);
/**
* Returns all {@link #getRawFixes() raw fixes} and marks them as delivered to the client identified by <code>clientId</code>
* so that when that ID appears in a subsequent call to {@link #add(RaceLogEvent, UUID)}, the fixes returned by this call
* are already considered delivered to the client identified by <code>clientId</code>.
*/
Iterable<RaceLogEvent> getRawFixes(UUID clientId);
/**
* Like {@link #add(RaceLogEvent)}, only that no events are triggered. Use this method only when loading a race log,
* e.g., from a replication or master data import or when loading from the database.
*
* @return <code>true</code> if the event was actually added which is the case if there was no equal event contained
* in this race log yet
*/
boolean load(RaceLogEvent event);
/**
* Search for the event by its {@code id}, which will perform poorly for a large number
* of events, as they are ordered by {@link TimePoint}.
* @param id
* @return
*/
RaceLogEvent getEventById(Serializable id);
/**
* Check, whether the {@code revokeEvent} actually revokes the event it specifies by its
* {@link RevokeEvent#getRevokedEventId()}.
* @param revokeEvent
* @return
*/
boolean isEventRevokedBy(RevokeEvent revokeEvent);
/**
* Get a {@link NavigableSet} of unrevoked events.
* @return
*/
NavigableSet<RaceLogEvent> getUnrevokedEvents();
/**
* Get a {@link NavigableSet} of unrevoked events.
* @return
*/
NavigableSet<RaceLogEvent> getUnrevokedEventsDescending();
/**
* Updates the event, based on the assumption that the id has remained the same.
* Listeners are not informed about this, so use with care.
*/
void update(RaceLogEvent event);
/**
* Deletes the event. Listeners are not informed about this, so use with care.
*/
void delete(RaceLogEvent event);
}
package com.sap.sailing.domain.racelog;
import java.io.Serializable;
import java.util.HashSet;
import java.util.NavigableSet;
import java.util.UUID;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.racelog.impl.RaceLogEventComparator;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Track;
/**
* Special kind of {@link Track} for recording {@link RaceLogEvent}s.
*
* <p>
* Keeps track of the {@link RaceLogEvent}'s pass and returns only the events of the current pass on
* {@link RaceLog#getFixes()}. Use {@link RaceLog#getRawFixes()} to receive all events in a {@link RaceLog}.
* </p>
*
* <p>
* Implementations should use the {@link RaceLogEventComparator} for sorting its content.
* </p>
*/
public interface RaceLog extends Track<RaceLogEvent>, WithID {
public static final int DefaultPassId = 0;
/**
* Gets the current pass id.
*
* @return the pass id.
*/
int getCurrentPassId();
/**
* Adds a {@link RaceLogEvent} to the {@link RaceLog}.
*
* @param event
* {@link RaceLogEvent} to be added.
* @return <code>true</code> if the element was added, <code>false</code> otherwise.
*/
boolean add(RaceLogEvent event);
/**
* Add a {@link RaceLogEventVisitor} as a listener for additions.
*/
void addListener(RaceLogEventVisitor listener);
/**
* Remove a listener.
*/
void removeListener(RaceLogEventVisitor listener);
/**
* Removes all listeners
* @return
*/
HashSet<RaceLogEventVisitor> removeAllListeners();
/**
* Checks if the race log is empty.
*/
boolean isEmpty();
Iterable<RaceLogEvent> getRawFixesDescending();
Iterable<RaceLogEvent> getFixesDescending();
void addAllListeners(HashSet<RaceLogEventVisitor> listeners);
Iterable<RaceLogEventVisitor> getAllListeners();
/**
* Adds an event to this race log and returns {@link RaceLog#getEventsToDeliver(UUID)}
* (excluding the new <code>event</code>)
*/
Iterable<RaceLogEvent> add(RaceLogEvent event, UUID clientId);
/**
* Returns a superset of all race log events that were added to this race log but not yet returned to
* the client with ID <code>clientId</code> by this method. In general, the list returned is not a true
* superset but equals exactly those events not yet delivered to the client. However, if the server
* was re-started since the client last called this method, and since the underlying data structures
* are not durably stored, the entire set of all race log events would be delivered to the client once.
*/
Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId);
/**
* Returns all {@link #getRawFixes() raw fixes} and marks them as delivered to the client identified by <code>clientId</code>
* so that when that ID appears in a subsequent call to {@link #add(RaceLogEvent, UUID)}, the fixes returned by this call
* are already considered delivered to the client identified by <code>clientId</code>.
*/
Iterable<RaceLogEvent> getRawFixes(UUID clientId);
/**
* Like {@link #add(RaceLogEvent)}, only that no events are triggered. Use this method only when loading a race log,
* e.g., from a replication or master data import or when loading from the database.
*
* @return <code>true</code> if the event was actually added which is the case if there was no equal event contained
* in this race log yet
*/
boolean load(RaceLogEvent event);
/**
* Search for the event by its {@code id}, which will perform poorly for a large number
* of events, as they are ordered by {@link TimePoint}.
* @param id
* @return
*/
RaceLogEvent getEventById(Serializable id);
/**
* Check, whether the {@code revokeEvent} actually revokes the event it specifies by its
* {@link RevokeEvent#getRevokedEventId()}.
* @param revokeEvent
* @return
*/
boolean isEventRevokedBy(RevokeEvent revokeEvent);
/**
* Get a {@link NavigableSet} of unrevoked events.
* @return
*/
NavigableSet<RaceLogEvent> getUnrevokedEvents();
/**
* Get a {@link NavigableSet} of unrevoked events.
* @return
*/
NavigableSet<RaceLogEvent> getUnrevokedEventsDescending();
}
@@ -228,18 +228,8 @@ public class NoAddingRaceLogWrapper implements RaceLog {
return innerRaceLog.getAverageIntervalBetweenRawFixes();
}
@Override
public void update(RaceLogEvent event) {
innerRaceLog.update(event);
}
@Override
public void delete(RaceLogEvent event) {
innerRaceLog.delete(event);
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEventsDescending() {
return innerRaceLog.getUnrevokedEventsDescending();
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEventsDescending() {
return innerRaceLog.getUnrevokedEventsDescending();
}
}
@@ -34,17 +34,12 @@ public enum RaceLogEventComparator implements Comparator<Timed>, Serializable {
}
private int compareEvents(RaceLogEvent e1, RaceLogEvent e2) {
boolean result = compareIds(e1, e2);
return result ? 0 : comparePasses(e1, e2);
}
private boolean compareIds(RaceLogEvent e1, RaceLogEvent e2) {
return e1.getId().equals(e2.getId());
int result = comparePasses(e1, e2);
return result == 0 ? compareAuthorPriorities(e1, e2) : result;
}
private int comparePasses(RaceLogEvent e1, RaceLogEvent e2) {
int result = e1.getPassId() - e2.getPassId();
return result == 0 ? compareAuthorPriorities(e1, e2) : result;
return e1.getPassId() - e2.getPassId();
}
private int compareAuthorPriorities(RaceLogEvent e1, RaceLogEvent e2) {
@@ -54,7 +49,11 @@ public enum RaceLogEventComparator implements Comparator<Timed>, Serializable {
private int compareCreatedAtTimes(RaceLogEvent e1, RaceLogEvent e2) {
int result = e1.getCreatedAt().compareTo(e2.getCreatedAt());
return result == 0 ? -1 : result;
return result == 0 ? compareIds(e1, e2) : result;
}
private int compareIds(RaceLogEvent e1, RaceLogEvent e2) {
return e1.getId().toString().compareTo(e2.getId().toString());
}
}
@@ -78,12 +78,4 @@ public abstract class RaceLogEventImpl implements RaceLogEvent {
public String getShortInfo() {
return "";
}
@Override
public boolean equals(Object arg0) {
if (arg0 instanceof RaceLogEvent) {
return getId().equals(((RaceLogEvent) arg0).getId());
}
return super.equals(arg0);
}
}
@@ -1,367 +1,339 @@
package com.sap.sailing.domain.racelog.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.impl.PartialNavigableSetView;
import com.sap.sailing.domain.tracking.impl.TrackImpl;
import com.sap.sailing.util.impl.ArrayListNavigableSet;
/**
* {@link Track} implementation for {@link RaceLogEvent}s.
*
* <p>
* "Fix" validity is decided based on the {@link #getCurrentPassId() current pass}. The validity is not cached.
* </p>
*
* <p>
* {@link TrackImpl#getDummyFix(com.sap.sailing.domain.common.TimePoint)} is not overridden, see
* {@link RaceLogEventComparator} for sorting when interface methods like
* {@link Track#getFirstFixAfter(com.sap.sailing.domain.common.TimePoint)} are used.
* </p>
*
*/
public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
private static final long serialVersionUID = -176745401321893502L;
private static final String DefaultLockName = RaceLogImpl.class.getName() + ".lock";
private final static Logger logger = Logger.getLogger(RaceLogImpl.class.getName());
private final Set<Serializable> revokedEventIds = new HashSet<Serializable>();
/**
* Clients can use the {@link #add(RaceLogEvent, UUID)} method
*/
private transient Map<UUID, Set<RaceLogEvent>> eventsDeliveredToClient = new HashMap<UUID, Set<RaceLogEvent>>();
private final Serializable id;
private transient Set<RaceLogEventVisitor> listeners;
private int currentPassId;
/**
* Initializes a new {@link RaceLogImpl} with the default lock name.
*/
public RaceLogImpl(Serializable identifier) {
this(DefaultLockName, identifier);
}
/**
* Initializes a new {@link RaceLogImpl}.
*
* @param nameForReadWriteLock
* name of lock.
*/
public RaceLogImpl(String nameForReadWriteLock, Serializable identifier) {
super(new ArrayListNavigableSet<Timed>(RaceLogEventComparator.INSTANCE), nameForReadWriteLock);
this.listeners = new HashSet<RaceLogEventVisitor>();
this.currentPassId = DefaultPassId;
this.id = identifier;
}
@Override
public Serializable getId() {
return this.id;
}
@Override
public int getCurrentPassId() {
return currentPassId;
}
/**
* Sets a new active pass id. Ignored if new and current are equal.
*
* @param newPassId
* to be set.
*/
public void setCurrentPassId(int newPassId) {
if (newPassId != this.currentPassId) {
logger.finer(String.format("Changing pass id to %d", newPassId));
this.currentPassId = newPassId;
}
}
@Override
public boolean add(RaceLogEvent event) {
boolean isAdded = false;
lockForWrite();
try {
isAdded = getInternalRawFixes().add(event);
} finally {
unlockAfterWrite();
}
if (isAdded) {
logger.finer(String.format("%s (%s) was added to log %s.", event, event.getClass().getName(), getId()));
// FIXME with out-of-order delivery would destroy currentPassId; need to check at least the createdAt time
// point
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
notifyListenersAboutReceive(event);
} else {
logger.warning(String.format("%s (%s) was not added to race log %s. Ignoring", event, event.getClass().getName(), getId()));
}
return isAdded;
}
@Override
public boolean load(RaceLogEvent event) {
boolean isAdded = false;
lockForWrite();
try {
isAdded = getInternalRawFixes().add(event);
} finally {
unlockAfterWrite();
}
if (isAdded) {
logger.finer(String.format("%s (%s) was loaded into log.", event, event.getClass().getName()));
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
} else {
logger.warning(String
.format("%s (%s) was not loaded into log. Ignoring", event, event.getClass().getName()));
}
return isAdded;
}
private void revokeIfNecessary(RaceLogEvent newEvent) {
if (newEvent instanceof RevokeEvent) {
RevokeEvent revokeEvent = (RevokeEvent) newEvent;
lockForRead();
RaceLogEvent revokedEvent = getEventById(revokeEvent.getRevokedEventId());
unlockAfterRead();
if (! (revokedEvent instanceof RevokeEvent) && isEventRevokedBy(revokeEvent)) {
lockForWrite();
revokedEventIds.add(revokeEvent.getRevokedEventId());
unlockAfterWrite();
} else {
logger.log(Level.FINE, "Not revoking event " + revokedEvent);
}
}
}
@Override
public Iterable<RaceLogEvent> add(RaceLogEvent event, UUID clientId) {
boolean isAdded = false;
lockForWrite();
try {
isAdded = getInternalRawFixes().add(event);
} finally {
unlockAfterWrite();
}
if (isAdded) {
logger.finer(String.format("%s (%s) was added to log.", event, event.getClass().getName()));
// FIXME with out-of-order delivery would destroy currentPassId; need to check at least the createdAt time
// point
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
notifyListenersAboutReceive(event);
} else {
logger.warning(String.format("%s (%s) was not added to log. Ignoring", event, event.getClass().getName()));
}
return getEventsToDeliver(clientId, event);
}
@Override
public Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId) {
return getEventsToDeliver(clientId, null);
}
protected Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId, RaceLogEvent suppressedEvent) {
final LinkedHashSet<RaceLogEvent> stillToDeliverToClient;
lockForRead();
try {
stillToDeliverToClient = new LinkedHashSet<RaceLogEvent>(getInternalRawFixes());
} finally {
unlockAfterRead();
}
stillToDeliverToClient.remove(suppressedEvent);
Set<RaceLogEvent> deliveredToClient = eventsDeliveredToClient.get(clientId);
if (deliveredToClient != null) {
stillToDeliverToClient.removeAll(deliveredToClient);
} else {
deliveredToClient = new HashSet<RaceLogEvent>();
eventsDeliveredToClient.put(clientId, deliveredToClient);
}
deliveredToClient.addAll(stillToDeliverToClient);
deliveredToClient.add(suppressedEvent);
return stillToDeliverToClient;
}
protected void notifyListenersAboutReceive(RaceLogEvent event) {
Set<RaceLogEventVisitor> workingListeners = new HashSet<RaceLogEventVisitor>();
synchronized (listeners) {
workingListeners.addAll(listeners);
}
for (RaceLogEventVisitor listener : workingListeners) {
try {
event.accept(listener);
} catch (Throwable t) {
logger.log(Level.SEVERE, "RaceLogEventVisitor " + listener + " threw exception " + t.getMessage());
logger.throwing(RaceLogImpl.class.getName(), "notifyListenersAboutReceive(RaceLogEvent)", t);
t.printStackTrace();
}
}
}
@Override
public boolean isEmpty() {
return getFirstRawFix() == null;
}
@Override
public void addListener(RaceLogEventVisitor listener) {
synchronized (listeners) {
listeners.add(listener);
}
}
@Override
public void removeListener(RaceLogEventVisitor listener) {
synchronized (listeners) {
listeners.remove(listener);
}
}
@Override
protected NavigableSet<RaceLogEvent> getInternalFixes() {
return new PartialNavigableSetView<RaceLogEvent>(super.getInternalFixes()) {
@Override
protected boolean isValid(RaceLogEvent e) {
return e.getPassId() == getCurrentPassId();
}
};
}
/**
* When deserializing, needs to initialize empty set of listeners.
*/
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
listeners = new HashSet<RaceLogEventVisitor>();
eventsDeliveredToClient = new HashMap<UUID, Set<RaceLogEvent>>();
}
@Override
public Iterable<RaceLogEvent> getRawFixesDescending() {
return getRawFixes().descendingSet();
}
@Override
public Iterable<RaceLogEvent> getFixesDescending() {
return getFixes().descendingSet();
}
@Override
public HashSet<RaceLogEventVisitor> removeAllListeners() {
synchronized (listeners) {
HashSet<RaceLogEventVisitor> clonedListeners = new HashSet<RaceLogEventVisitor>(listeners);
listeners = new HashSet<RaceLogEventVisitor>();
return clonedListeners;
}
}
@Override
public void addAllListeners(HashSet<RaceLogEventVisitor> listeners) {
synchronized (listeners) {
this.listeners.addAll(listeners);
}
}
@Override
public Iterable<RaceLogEventVisitor> getAllListeners() {
return this.listeners;
}
@Override
public Iterable<RaceLogEvent> getRawFixes(UUID clientId) {
assertReadLock();
NavigableSet<RaceLogEvent> result = getRawFixes();
Set<RaceLogEvent> edtc = eventsDeliveredToClient.get(clientId);
if (edtc == null) {
edtc = new HashSet<RaceLogEvent>();
eventsDeliveredToClient.put(clientId, edtc);
}
edtc.addAll(result);
return result;
}
@Override
public RaceLogEvent getEventById(Serializable id) {
lockForRead();
try {
for (RaceLogEvent e : getRawFixes()) {
if (e.getId().equals(id)) return e;
}
return null;
} finally {
unlockAfterRead();
}
}
@Override
public boolean isEventRevokedBy(RevokeEvent revokeEvent) {
lockForRead();
RaceLogEvent revokedEvent = getEventById(revokeEvent.getRevokedEventId());
unlockAfterRead();
return getInternalRawFixes().comparator().compare(revokeEvent, revokedEvent) > 0;
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEvents() {
return new PartialNavigableSetView<RaceLogEvent>(super.getInternalFixes()) {
@Override
protected boolean isValid(RaceLogEvent e) {
return ! (e instanceof RevokeEvent) && ! revokedEventIds.contains(e.getId());
}
};
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEventsDescending() {
return new PartialNavigableSetView<RaceLogEvent>(super.getInternalFixes().descendingSet()) {
@Override
protected boolean isValid(RaceLogEvent e) {
return ! (e instanceof RevokeEvent) && ! revokedEventIds.contains(e.getId());
}
};
}
@Override
public void update(RaceLogEvent event) {
lockForWrite();
try {
getInternalRawFixes().remove(event);
getInternalFixes().add(event);
}
finally {
unlockAfterWrite();
}
}
@Override
public void delete(RaceLogEvent event) {
lockForWrite();
try {
getInternalRawFixes().remove(event);
}
finally {
unlockAfterWrite();
}
}
}
package com.sap.sailing.domain.racelog.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.tracking.RevokeEvent;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.impl.PartialNavigableSetView;
import com.sap.sailing.domain.tracking.impl.TrackImpl;
import com.sap.sailing.util.impl.ArrayListNavigableSet;
/**
* {@link Track} implementation for {@link RaceLogEvent}s.
*
* <p>
* "Fix" validity is decided based on the {@link #getCurrentPassId() current pass}. The validity is not cached.
* </p>
*
* <p>
* {@link TrackImpl#getDummyFix(com.sap.sailing.domain.common.TimePoint)} is not overridden, see
* {@link RaceLogEventComparator} for sorting when interface methods like
* {@link Track#getFirstFixAfter(com.sap.sailing.domain.common.TimePoint)} are used.
* </p>
*
*/
public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
private static final long serialVersionUID = -176745401321893502L;
private static final String DefaultLockName = RaceLogImpl.class.getName() + ".lock";
private final static Logger logger = Logger.getLogger(RaceLogImpl.class.getName());
private final Set<Serializable> revokedEventIds = new HashSet<Serializable>();
/**
* Clients can use the {@link #add(RaceLogEvent, UUID)} method
*/
private transient Map<UUID, Set<RaceLogEvent>> eventsDeliveredToClient = new HashMap<UUID, Set<RaceLogEvent>>();
private final Serializable id;
private transient Set<RaceLogEventVisitor> listeners;
private int currentPassId;
/**
* Initializes a new {@link RaceLogImpl} with the default lock name.
*/
public RaceLogImpl(Serializable identifier) {
this(DefaultLockName, identifier);
}
/**
* Initializes a new {@link RaceLogImpl}.
*
* @param nameForReadWriteLock
* name of lock.
*/
public RaceLogImpl(String nameForReadWriteLock, Serializable identifier) {
super(new ArrayListNavigableSet<Timed>(RaceLogEventComparator.INSTANCE), nameForReadWriteLock);
this.listeners = new HashSet<RaceLogEventVisitor>();
this.currentPassId = DefaultPassId;
this.id = identifier;
}
@Override
public Serializable getId() {
return this.id;
}
@Override
public int getCurrentPassId() {
return currentPassId;
}
/**
* Sets a new active pass id. Ignored if new and current are equal.
*
* @param newPassId
* to be set.
*/
public void setCurrentPassId(int newPassId) {
if (newPassId != this.currentPassId) {
logger.finer(String.format("Changing pass id to %d", newPassId));
this.currentPassId = newPassId;
}
}
@Override
public boolean add(RaceLogEvent event) {
boolean isAdded = false;
lockForWrite();
try {
isAdded = getInternalRawFixes().add(event);
} finally {
unlockAfterWrite();
}
if (isAdded) {
logger.finer(String.format("%s (%s) was added to log %s.", event, event.getClass().getName(), getId()));
// FIXME with out-of-order delivery would destroy currentPassId; need to check at least the createdAt time
// point
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
notifyListenersAboutReceive(event);
} else {
logger.warning(String.format("%s (%s) was not added to race log %s. Ignoring", event, event.getClass().getName(), getId()));
}
return isAdded;
}
@Override
public boolean load(RaceLogEvent event) {
boolean isAdded = false;
lockForWrite();
try {
isAdded = getInternalRawFixes().add(event);
} finally {
unlockAfterWrite();
}
if (isAdded) {
logger.finer(String.format("%s (%s) was loaded into log.", event, event.getClass().getName()));
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
} else {
logger.warning(String
.format("%s (%s) was not loaded into log. Ignoring", event, event.getClass().getName()));
}
return isAdded;
}
private void revokeIfNecessary(RaceLogEvent newEvent) {
if (newEvent instanceof RevokeEvent) {
RevokeEvent revokeEvent = (RevokeEvent) newEvent;
lockForRead();
RaceLogEvent revokedEvent = getEventById(revokeEvent.getRevokedEventId());
unlockAfterRead();
if (! (revokedEvent instanceof RevokeEvent) && isEventRevokedBy(revokeEvent)) {
lockForWrite();
revokedEventIds.add(revokeEvent.getRevokedEventId());
unlockAfterWrite();
} else {
logger.log(Level.FINE, "Not revoking event " + revokedEvent);
}
}
}
@Override
public Iterable<RaceLogEvent> add(RaceLogEvent event, UUID clientId) {
boolean isAdded = false;
lockForWrite();
try {
isAdded = getInternalRawFixes().add(event);
} finally {
unlockAfterWrite();
}
if (isAdded) {
logger.finer(String.format("%s (%s) was added to log.", event, event.getClass().getName()));
// FIXME with out-of-order delivery would destroy currentPassId; need to check at least the createdAt time
// point
setCurrentPassId(Math.max(event.getPassId(), this.currentPassId));
revokeIfNecessary(event);
notifyListenersAboutReceive(event);
} else {
logger.warning(String.format("%s (%s) was not added to log. Ignoring", event, event.getClass().getName()));
}
return getEventsToDeliver(clientId, event);
}
@Override
public Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId) {
return getEventsToDeliver(clientId, null);
}
protected Iterable<RaceLogEvent> getEventsToDeliver(UUID clientId, RaceLogEvent suppressedEvent) {
final LinkedHashSet<RaceLogEvent> stillToDeliverToClient;
lockForRead();
try {
stillToDeliverToClient = new LinkedHashSet<RaceLogEvent>(getInternalRawFixes());
} finally {
unlockAfterRead();
}
stillToDeliverToClient.remove(suppressedEvent);
Set<RaceLogEvent> deliveredToClient = eventsDeliveredToClient.get(clientId);
if (deliveredToClient != null) {
stillToDeliverToClient.removeAll(deliveredToClient);
} else {
deliveredToClient = new HashSet<RaceLogEvent>();
eventsDeliveredToClient.put(clientId, deliveredToClient);
}
deliveredToClient.addAll(stillToDeliverToClient);
deliveredToClient.add(suppressedEvent);
return stillToDeliverToClient;
}
protected void notifyListenersAboutReceive(RaceLogEvent event) {
Set<RaceLogEventVisitor> workingListeners = new HashSet<RaceLogEventVisitor>();
synchronized (listeners) {
workingListeners.addAll(listeners);
}
for (RaceLogEventVisitor listener : workingListeners) {
try {
event.accept(listener);
} catch (Throwable t) {
logger.log(Level.SEVERE, "RaceLogEventVisitor " + listener + " threw exception " + t.getMessage());
logger.throwing(RaceLogImpl.class.getName(), "notifyListenersAboutReceive(RaceLogEvent)", t);
t.printStackTrace();
}
}
}
@Override
public boolean isEmpty() {
return getFirstRawFix() == null;
}
@Override
public void addListener(RaceLogEventVisitor listener) {
synchronized (listeners) {
listeners.add(listener);
}
}
@Override
public void removeListener(RaceLogEventVisitor listener) {
synchronized (listeners) {
listeners.remove(listener);
}
}
@Override
protected NavigableSet<RaceLogEvent> getInternalFixes() {
return new PartialNavigableSetView<RaceLogEvent>(super.getInternalFixes()) {
@Override
protected boolean isValid(RaceLogEvent e) {
return e.getPassId() == getCurrentPassId();
}
};
}
/**
* When deserializing, needs to initialize empty set of listeners.
*/
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
listeners = new HashSet<RaceLogEventVisitor>();
eventsDeliveredToClient = new HashMap<UUID, Set<RaceLogEvent>>();
}
@Override
public Iterable<RaceLogEvent> getRawFixesDescending() {
return getRawFixes().descendingSet();
}
@Override
public Iterable<RaceLogEvent> getFixesDescending() {
return getFixes().descendingSet();
}
@Override
public HashSet<RaceLogEventVisitor> removeAllListeners() {
synchronized (listeners) {
HashSet<RaceLogEventVisitor> clonedListeners = new HashSet<RaceLogEventVisitor>(listeners);
listeners = new HashSet<RaceLogEventVisitor>();
return clonedListeners;
}
}
@Override
public void addAllListeners(HashSet<RaceLogEventVisitor> listeners) {
synchronized (listeners) {
this.listeners.addAll(listeners);
}
}
@Override
public Iterable<RaceLogEventVisitor> getAllListeners() {
return this.listeners;
}
@Override
public Iterable<RaceLogEvent> getRawFixes(UUID clientId) {
assertReadLock();
NavigableSet<RaceLogEvent> result = getRawFixes();
Set<RaceLogEvent> edtc = eventsDeliveredToClient.get(clientId);
if (edtc == null) {
edtc = new HashSet<RaceLogEvent>();
eventsDeliveredToClient.put(clientId, edtc);
}
edtc.addAll(result);
return result;
}
@Override
public RaceLogEvent getEventById(Serializable id) {
for (RaceLogEvent e : getRawFixes()) {
if (e.getId().equals(id)) return e;
}
return null;
}
@Override
public boolean isEventRevokedBy(RevokeEvent revokeEvent) {
lockForRead();
RaceLogEvent revokedEvent = getEventById(revokeEvent.getRevokedEventId());
unlockAfterRead();
return getInternalRawFixes().comparator().compare(revokeEvent, revokedEvent) > 0;
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEvents() {
return new PartialNavigableSetView<RaceLogEvent>(super.getInternalFixes()) {
@Override
protected boolean isValid(RaceLogEvent e) {
return ! (e instanceof RevokeEvent) && ! revokedEventIds.contains(e.getId());
}
};
}
@Override
public NavigableSet<RaceLogEvent> getUnrevokedEventsDescending() {
return new PartialNavigableSetView<RaceLogEvent>(super.getInternalFixes().descendingSet()) {
@Override
protected boolean isValid(RaceLogEvent e) {
return ! (e instanceof RevokeEvent) && ! revokedEventIds.contains(e.getId());
}
};
}
}
@@ -19,6 +19,7 @@ public class RaceLogTrackingStateAnalyzer extends RaceLogAnalyzer<RaceLogTrackin
if (event instanceof StartTrackingEvent) {
return RaceLogTrackingState.TRACKING;
} else if (event instanceof DenoteForTrackingEvent) {
System.out.println(RaceLogTrackingState.AWAITING_RACE_DEFINITION);
return RaceLogTrackingState.AWAITING_RACE_DEFINITION;
}
}
@@ -30,8 +30,7 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sailing.datamining.shared;bundle-version="1.0.0",
com.sap.sailing.datamining;bundle-version="1.0.0",
com.sap.sse.gwt;bundle-version="1.0.0",
com.sap.sailing.domain.racelogtrackingadapter;bundle-version="1.0.0",
com.sap.sailing.server.gateway.serialization;bundle-version="1.0.0"
com.sap.sailing.domain.racelogtrackingadapter;bundle-version="1.0.0"
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
Bundle-ActivationPolicy: lazy
Import-Package: javax.jms;version="1.1.0",
@@ -39,7 +39,6 @@
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server.gateway.serialization/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
-6
View File
@@ -66,12 +66,6 @@
<version>2.3.2.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sap.sailing</groupId>
<artifactId>com.sap.sailing.server.gateway.serialization</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>1.0.0-SNAPSHOT</scope>
</dependency>
</dependencies>
<build>
@@ -796,7 +796,7 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
}
private void openRaceLogDialog(RaceLogDTO raceLogDTO) {
RaceLogDialog dialog = new RaceLogDialog(sailingService, errorReporter, raceLogDTO, stringMessages, new DialogCallback<RaceLogDTO>() {
RaceLogDialog dialog = new RaceLogDialog(raceLogDTO, stringMessages, new DialogCallback<RaceLogDTO>() {
@Override
public void cancel() {
}
@@ -4,51 +4,29 @@ import java.util.Comparator;
import java.util.Date;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.google.gwt.view.client.SelectionModel;
import com.google.gwt.view.client.SingleSelectionModel;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.RaceLogDTO;
import com.sap.sailing.gwt.ui.shared.RaceLogEventDTO;
import com.sap.sse.gwt.ui.DataEntryDialog;
public class RaceLogDialog extends DataEntryDialog<RaceLogDTO> {
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
private RaceLogDTO raceLogDTO;
private final TextArea editEventBox;
private final Button saveButton;
private Label currentPassLabel;
private Button deleteEventButton;
private final RaceLogDTO raceLogDTO;
private final SingleSelectionModel<RaceLogEventDTO> selectionModel;
private final SelectionModel<RaceLogEventDTO> selectionModel;
private final CellTable<RaceLogEventDTO> raceLogEventsTable;
private ListDataProvider<RaceLogEventDTO> raceLogEventsList;
private final Panel editPanel;
protected static class RaceLogValidator implements Validator<RaceLogDTO> {
public RaceLogValidator() {
@@ -61,10 +39,8 @@ public class RaceLogDialog extends DataEntryDialog<RaceLogDTO> {
}
}
public RaceLogDialog(SailingServiceAsync sailingService, ErrorReporter errorReporter, final RaceLogDTO raceLogDTO, final StringMessages stringMessages, DialogCallback<RaceLogDTO> callback) {
public RaceLogDialog(final RaceLogDTO raceLogDTO, final StringMessages stringMessages, DialogCallback<RaceLogDTO> callback) {
super(stringMessages.raceLog(), null, stringMessages.ok(), stringMessages.cancel(), new RaceLogValidator(), callback);
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.stringMessages = stringMessages;
this.raceLogDTO = raceLogDTO;
@@ -185,94 +161,6 @@ public class RaceLogDialog extends DataEntryDialog<RaceLogDTO> {
raceLogEventsList.addDataDisplay(raceLogEventsTable);
raceLogEventsTable.getColumnSortList().push(raceLogEventLogicalTimeColumn);
editPanel = new VerticalPanel();
editEventBox = new TextArea();
editEventBox.setSize("880px", "70px");
editPanel.add(editEventBox);
saveButton = new Button(stringMessages.add());
saveButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
saveEditedEvent(selectionModel.getSelectedObject(), editEventBox.getText());
}
});
editPanel.add(saveButton);
selectionModel.addSelectionChangeHandler(new Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
loadEvent(selectionModel.getSelectedObject());
}
});
}
private void updateRaceLog() {
RaceColumnDTO raceColumn = new RaceColumnDTO(false);
raceColumn.setName(raceLogDTO.getRaceColumnName());
FleetDTO fleet = new FleetDTO(raceLogDTO.getFleetName(), 0, null);
sailingService.getRaceLog(raceLogDTO.getLeaderboardName(), raceColumn, fleet, new AsyncCallback<RaceLogDTO>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Failed to reload RaceLog: " + caught.getMessage());
}
@Override
public void onSuccess(RaceLogDTO result) {
editEventBox.setText("");
raceLogDTO = result;
raceLogEventsList.setList(raceLogDTO.getEntries());
raceLogEventsList.refresh();
currentPassLabel.setText(stringMessages.currentPass() + ":" + raceLogDTO.getCurrentPassId());
}
});
}
private void saveEditedEvent(RaceLogEventDTO event, String newText) {
try {
JSONValue json = JSONParser.parseStrict(newText);
sailingService.addOrUpdateRaceLogEvent(raceLogDTO.getLeaderboardName(), raceLogDTO.getRaceColumnName(),
raceLogDTO.getFleetName(), json.toString(), new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
updateRaceLog();
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not update event: " + caught.getMessage());
}
});
} catch (IllegalArgumentException e) {
errorReporter.reportError("Invalid JSON format: " + e.getMessage());
} catch (NullPointerException e) {
errorReporter.reportError("Invalid JSON format: " + e.getMessage());
}
}
private void loadEvent(RaceLogEventDTO event) {
if (event != null) {
deleteEventButton.setVisible(true);
sailingService.getRaceLogEvent(raceLogDTO.getLeaderboardName(), raceLogDTO.getRaceColumnName(),
raceLogDTO.getFleetName(), event.getEventId(), new AsyncCallback<String>() {
@Override
public void onSuccess(String result) {
editEventBox.setText(result);
saveButton.setText(stringMessages.save());
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not load RaceLogEvent: " + caught.getMessage());
}
});
} else {
editEventBox.setText("");
saveButton.setText(stringMessages.add());
deleteEventButton.setVisible(false);
}
}
@Override
@@ -284,43 +172,14 @@ public class RaceLogDialog extends DataEntryDialog<RaceLogDTO> {
protected Widget getAdditionalWidget() {
VerticalPanel vPanel = new VerticalPanel();
HorizontalPanel titlePanel = new HorizontalPanel();
vPanel.add(titlePanel);
currentPassLabel = new Label(stringMessages.currentPass() + ":" + raceLogDTO.getCurrentPassId());
titlePanel.add(currentPassLabel);
deleteEventButton = new Button(stringMessages.delete());
deleteEventButton.setVisible(false);
titlePanel.add(deleteEventButton);
deleteEventButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent clickEvent) {
RaceLogEventDTO event = selectionModel.getSelectedObject();
if (event != null) {
sailingService.deleteRaceLogEvent(raceLogDTO.getLeaderboardName(), raceLogDTO.getRaceColumnName(),
raceLogDTO.getFleetName(), event.getEventId(), new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
updateRaceLog();
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not delete event: " + caught.getMessage());
}
});
}
}
});
Label currentPassLabel = new Label(stringMessages.currentPass() + ":" + raceLogDTO.getCurrentPassId());
vPanel.add(currentPassLabel);
ScrollPanel scrollPanel = new ScrollPanel(raceLogEventsTable);
scrollPanel.setSize("960px", "400px");
scrollPanel.setSize("960px", "500px");
vPanel.add(scrollPanel);
vPanel.add(editPanel);
return vPanel;
}
}
@@ -1,6 +1,5 @@
package com.sap.sailing.gwt.ui.client;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -343,8 +342,6 @@ public interface SailingService extends RemoteService {
RaceLogDTO getRaceLog(String leaderboardName, RaceColumnDTO raceColumnDTO, FleetDTO fleet);
String getRaceLogEvent(String leaderboardName, String raceColumnName, String fleetName, Serializable eventId);
MasterDataImportObjectCreationCount importMasterData(String host, String[] groupNames, boolean override, boolean compress);
<ResultType extends Number> QueryResult<ResultType> runQuery(QueryDefinition queryDefinition) throws Exception;
@@ -386,9 +383,4 @@ public interface SailingService extends RemoteService {
void addRaceLogTracker(String leaderboardName, String raceColumnName, String fleetName) throws Exception, RaceNotCreatedException;
void denoteForRaceLogTracking(String leaderboardName, String raceColumnName, String fleetName) throws Exception;
void addOrUpdateRaceLogEvent(String leaderboardName, String raceColumnName, String fleetName, String jsonEvent)
throws Exception;
void deleteRaceLogEvent(String leaderboardName, String raceColumnName, String fleetName, Serializable eventId);
}
@@ -1,6 +1,5 @@
package com.sap.sailing.gwt.ui.client;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -524,15 +523,5 @@ public interface SailingServiceAsync {
void denoteForRaceLogTracking(String leaderboardName,
String raceColumnName, String fleetName,
AsyncCallback<Void> callback);
void getRaceLogEvent(String leaderboardName, String raceColumnName,
String fleetName, Serializable eventId,
AsyncCallback<String> callback);
void addOrUpdateRaceLogEvent(String leaderboardName, String raceColumnName,
String fleetName, String jsonEvent, AsyncCallback<Void> callback);
void deleteRaceLogEvent(String leaderboardName, String raceColumnName,
String fleetName, Serializable eventId, AsyncCallback<Void> callback);
}
@@ -1,6 +1,5 @@
package com.sap.sailing.gwt.ui.shared;
import java.io.Serializable;
import java.util.Date;
import com.google.gwt.user.client.rpc.IsSerializable;
@@ -9,7 +8,6 @@ import com.google.gwt.user.client.rpc.IsSerializable;
* DTO for a race log entry.
*/
public class RaceLogEventDTO implements IsSerializable {
private Serializable eventId;
private Integer passId;
private String authorName;
private Integer authorPriority;
@@ -24,9 +22,8 @@ public class RaceLogEventDTO implements IsSerializable {
RaceLogEventDTO() {}
public RaceLogEventDTO(Serializable eventId, int passId, String authorName, Integer authorPriority, Date createdAt, Date logicalTimePoint,
public RaceLogEventDTO(int passId, String authorName, Integer authorPriority, Date createdAt, Date logicalTimePoint,
String type, String info) {
this.eventId = eventId;
this.passId = passId;
this.authorName = authorName;
this.authorPriority = authorPriority;
@@ -70,8 +67,4 @@ public class RaceLogEventDTO implements IsSerializable {
public Date getCreatedAt() {
return createdAt;
}
public Serializable getEventId() {
return eventId;
}
}
@@ -27,7 +27,6 @@
<inherits name="com.sap.sailing.gwt.ui.EmulatedJRE" />
<inherits name="com.sap.sse.gwt.SSESharedGWT" />
<inherits name="com.sap.sailing.domain.SailingDomain" />
<inherits name="com.sap.sailing.server.gateway.GatewaySerialization" />
<inherits name="com.sap.sailing.datamining.DataMiningDomain" />
<inherits name="de.csenk.gwt.ws.WebSocket" />
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.4.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-module.dtd">
<module>
<source path='deserialization'/>
</module>
@@ -1,5 +1,7 @@
package com.sap.sailing.server.gateway.deserialization;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
/**
@@ -9,7 +11,7 @@ public class JsonDeserializationException extends TransformationException {
private static final long serialVersionUID = -6725762788023063937L;
public JsonDeserializationException() {
super("JSONObject");
super(JSONObject.class, null, null);
}
public JsonDeserializationException(String message, Throwable innerException) {
@@ -38,7 +38,6 @@ 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.common.racelog.tracking.TypeBasedServiceFinderFactory;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
@@ -487,6 +486,4 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
RaceTracker getRaceTrackerById(Object id);
RaceLogEventAuthor getServerAuthor();
TypeBasedServiceFinderFactory getServiceFinderFactory();
}
@@ -251,8 +251,6 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
private final WindStore windStore;
private final GPSFixStore gpsFixStore;
private final TypeBasedServiceFinderFactory serviceFinderFactory;
/**
* This author should be used for server generated race log events
*/
@@ -374,7 +372,6 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
this.raceLogScoringReplicator = new RaceLogScoringReplicator(this);
this.mediaDB = mediaDb;
this.mediaLibrary = new MediaLibrary();
this.serviceFinderFactory = serviceFinderFactory;
if (windStore == null) {
try {
windStore = MongoWindStoreFactory.INSTANCE.getMongoWindStore(mongoObjectFactory, domainObjectFactory);
@@ -2232,9 +2229,4 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
public RaceLogEventAuthor getServerAuthor() {
return raceLogEventAuthorForServer;
}
@Override
public TypeBasedServiceFinderFactory getServiceFinderFactory() {
return serviceFinderFactory;
}
}