mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-09 22:01:02 +00:00
implemented de-serialization through DomainFactory for Buoy, Competitor, Nationality, Waypoint, ControlPoint
This commit is contained in:
1 parent
652eaa5efa
commit
987fbfb30e
24 files changed
+273
-54
No files matched your search
@@ -4,7 +4,7 @@ import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Named;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
|
||||
public interface BoatClass extends Named {
|
||||
public interface BoatClass extends Named, IsManagedByDomainFactory {
|
||||
/**
|
||||
* The distance returned by this method should be appropriate for use in
|
||||
* {@link TrackedRace#approximate(Competitor, Distance, TimePoint, TimePoint)} so that penalty circles and other
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
public interface Buoy extends ControlPoint {
|
||||
/**
|
||||
* A buoy's name is used as its ID which is only identifying the buoy uniquely within a single race or course
|
||||
* definition.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface Buoy extends WithID, ControlPoint, IsManagedByDomainFactory {
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sailing.domain.common.Named;
|
||||
|
||||
public interface Competitor extends Named, WithID {
|
||||
public interface Competitor extends Named, WithID, IsManagedByDomainFactory {
|
||||
Team getTeam();
|
||||
|
||||
Boat getBoat();
|
||||
|
||||
@@ -15,13 +15,24 @@ public interface DomainFactory {
|
||||
* Looks up or, if not found, creates a {@link Nationality} object and re-uses <code>threeLetterIOCCode</code> also as the
|
||||
* nationality's name.
|
||||
*/
|
||||
Nationality getOrCreateNationality(String nationalityName);
|
||||
Nationality getOrCreateNationality(String threeLetterIOCCode);
|
||||
|
||||
Buoy getOrCreateBuoy(String id);
|
||||
|
||||
Gate createGate(Buoy left, Buoy right, String name);
|
||||
|
||||
/**
|
||||
* The waypoint created is weakly cached so that when requested again by
|
||||
* {@link #getExistingWaypointById(Serializable)} it is found.
|
||||
*/
|
||||
Waypoint createWaypoint(ControlPoint controlPoint);
|
||||
|
||||
Waypoint getExistingWaypointById(Serializable id);
|
||||
|
||||
/**
|
||||
* Caches an existing waypoint. This is useful, e.g., after de-serialization of a waypoint that has a yet unknown ID.
|
||||
*/
|
||||
void cacheWaypoint(Waypoint waypoint);
|
||||
|
||||
MarkPassing createMarkPassing(TimePoint timePoint, Waypoint waypoint, Competitor competitor);
|
||||
|
||||
@@ -31,10 +42,13 @@ public interface DomainFactory {
|
||||
|
||||
Competitor createCompetitor(Serializable id, String name, Team team, Boat boat);
|
||||
|
||||
Competitor getOrCreateCompetitor(Serializable competitorId, String name, Team team, Boat boat);
|
||||
|
||||
/**
|
||||
* When de-serializing objects of types whose instances that are managed and cached by this domain factory,
|
||||
* de-serialized instances need to be replaced by / resolved to the counterparts already known by this factory.
|
||||
* The stream returned by this method can be used
|
||||
*/
|
||||
ObjectInputStreamResolvingAgainstDomainFactory createObjectInputStreamResolvingAgainstThisFactory(InputStream inputStream) throws IOException;
|
||||
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
|
||||
/**
|
||||
* Classes implementing this interface have their instance life cycle managed by a {@link DomainFactory}. This is important
|
||||
* particularly during de-serialization when the de-serialized instance needs to be replaced by an instance managed by
|
||||
* the domain factory.<p>
|
||||
*
|
||||
* If the de-serializing stream is a {@link ObjectInputStreamResolvingAgainstDomainFactory} stream, it will automatically
|
||||
* do a {@link #resolve(Object)} for instances whose classes implement this interface. Implementing classes need to
|
||||
* delegate accordingly to the domain factory passed as argument.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public interface IsManagedByDomainFactory {
|
||||
IsManagedByDomainFactory resolve(DomainFactory domainFactory);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package com.sap.sailing.domain.base;
|
||||
import com.sap.sailing.domain.common.CountryCode;
|
||||
import com.sap.sailing.domain.common.Named;
|
||||
|
||||
public interface Nationality extends Named, WithImage {
|
||||
public interface Nationality extends Named, WithImage, IsManagedByDomainFactory {
|
||||
String getThreeLetterIOCAcronym();
|
||||
|
||||
CountryCode getCountryCode();
|
||||
|
||||
+14
-1
@@ -22,11 +22,13 @@ public abstract class ObjectInputStreamResolvingAgainstDomainFactory extends Obj
|
||||
|
||||
/**
|
||||
* Package protected on purpose; instances to be created using
|
||||
* {@link DomainFactory#createObjectInputStreamResolvingAgainstThisFactory(InputStream)}.
|
||||
* {@link DomainFactory#createObjectInputStreamResolvingAgainstThisFactory(InputStream)}. This constructor
|
||||
* {@link #enableResolveObject(boolean) enables resolving} by default.
|
||||
*/
|
||||
protected ObjectInputStreamResolvingAgainstDomainFactory(InputStream in, DomainFactory domainFactory) throws IOException {
|
||||
super(in);
|
||||
this.domainFactory = domainFactory;
|
||||
enableResolveObject(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,4 +41,15 @@ public abstract class ObjectInputStreamResolvingAgainstDomainFactory extends Obj
|
||||
String className = classDesc.getName();
|
||||
return Thread.currentThread().getContextClassLoader().loadClass(className);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object resolveObject(Object o) {
|
||||
Object result;
|
||||
if (o instanceof IsManagedByDomainFactory) {
|
||||
result = ((IsManagedByDomainFactory) o).resolve(getDomainFactory());
|
||||
} else {
|
||||
result = o;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import com.sap.sailing.domain.common.Named;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface Waypoint extends Named, WithID {
|
||||
public interface Waypoint extends Named, WithID, IsManagedByDomainFactory {
|
||||
ControlPoint getControlPoint();
|
||||
|
||||
Iterable<Buoy> getBuoys();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.impl.NamedImpl;
|
||||
|
||||
@@ -99,4 +100,10 @@ public class BoatClassImpl extends NamedImpl implements BoatClass {
|
||||
private double getConfidenceMultiplierForClusterSize(int numberOfBoatsInSmallestCluster) {
|
||||
return 1.0 + 1.0/1000000.0 - 1.0/(double) numberOfBoatsInSmallestCluster;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoatClass resolve(DomainFactory domainFactory) {
|
||||
return domainFactory.getOrCreateBoatClass(getName(), typicallyStartsUpwind());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.sap.sailing.domain.base.Buoy;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.common.impl.NamedImpl;
|
||||
|
||||
public class BuoyImpl extends NamedImpl implements Buoy {
|
||||
@@ -11,6 +13,11 @@ public class BuoyImpl extends NamedImpl implements Buoy {
|
||||
public BuoyImpl(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getId() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@@ -19,4 +26,9 @@ public class BuoyImpl extends NamedImpl implements Buoy {
|
||||
return (Iterable<Buoy>) result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Buoy resolve(DomainFactory domainFactory) {
|
||||
Buoy result = domainFactory.getOrCreateBuoy(getName());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Team;
|
||||
import com.sap.sailing.domain.common.impl.NamedImpl;
|
||||
|
||||
@@ -35,4 +36,9 @@ public class CompetitorImpl extends NamedImpl implements Competitor {
|
||||
return boat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor resolve(DomainFactory domainFactory) {
|
||||
Competitor result = domainFactory.getOrCreateCompetitor(getId(), getName(), getTeam(), getBoat());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+36
-8
@@ -6,6 +6,7 @@ import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
@@ -25,7 +26,7 @@ import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
||||
public class DomainFactoryImpl implements DomainFactory {
|
||||
/**
|
||||
* Ensure that the <em>same</em> string is used as key that is also used to set the {@link Nationality}
|
||||
* object's {@link Nationality#getName() name}.
|
||||
* object's {@link Nationality#getThreeLetterIOCAcronym() IOC code}.
|
||||
*/
|
||||
private final Map<String, Nationality> nationalityCache;
|
||||
|
||||
@@ -34,21 +35,24 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
private final Map<String, BoatClass> boatClassCache;
|
||||
|
||||
private final Map<Serializable, Competitor> competitorCache;
|
||||
|
||||
private final WeakHashMap<Serializable, Waypoint> waypointCache;
|
||||
|
||||
public DomainFactoryImpl() {
|
||||
nationalityCache = new HashMap<String, Nationality>();
|
||||
buoyCache = new HashMap<String, Buoy>();
|
||||
boatClassCache = new HashMap<String, BoatClass>();
|
||||
competitorCache = new HashMap<Serializable, Competitor>();
|
||||
waypointCache = new WeakHashMap<Serializable, Waypoint>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Nationality getOrCreateNationality(String nationalityName) {
|
||||
public Nationality getOrCreateNationality(String threeLetterIOCCode) {
|
||||
synchronized (nationalityCache) {
|
||||
Nationality result = nationalityCache.get(nationalityName);
|
||||
Nationality result = nationalityCache.get(threeLetterIOCCode);
|
||||
if (result == null) {
|
||||
result = new NationalityImpl(nationalityName, nationalityName);
|
||||
nationalityCache.put(nationalityName, result);
|
||||
result = new NationalityImpl(threeLetterIOCCode);
|
||||
nationalityCache.put(threeLetterIOCCode, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -75,8 +79,23 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint createWaypoint(ControlPoint controlPoint) {
|
||||
return new WaypointImpl(controlPoint);
|
||||
public synchronized Waypoint createWaypoint(ControlPoint controlPoint) {
|
||||
Waypoint result = new WaypointImpl(controlPoint);
|
||||
waypointCache.put(result.getId(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void cacheWaypoint(Waypoint waypoint) {
|
||||
if (getExistingWaypointById(waypoint.getId()) != null) {
|
||||
throw new IllegalArgumentException("Trying to cache an already cached waypoint: "+waypoint);
|
||||
}
|
||||
waypointCache.put(waypoint.getId(), waypoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint getExistingWaypointById(Serializable id) {
|
||||
return waypointCache.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,11 +121,20 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor createCompetitor(Serializable id, String name, Team team, Boat boat) {
|
||||
public synchronized Competitor createCompetitor(Serializable id, String name, Team team, Boat boat) {
|
||||
Competitor result = new CompetitorImpl(id, name, team, boat);
|
||||
competitorCache.put(id, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Competitor getOrCreateCompetitor(Serializable competitorId, String name, Team team, Boat boat) {
|
||||
Competitor result = getExistingCompetitorById(competitorId);
|
||||
if (result == null) {
|
||||
result = createCompetitor(competitorId, name, team, boat);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectInputStreamResolvingAgainstDomainFactory createObjectInputStreamResolvingAgainstThisFactory(
|
||||
|
||||
+8
-1
@@ -2,6 +2,8 @@ package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.IsManagedByDomainFactory;
|
||||
import com.sap.sailing.domain.base.Nationality;
|
||||
import com.sap.sailing.domain.common.CountryCode;
|
||||
import com.sap.sailing.domain.common.CountryCodeFactory;
|
||||
@@ -10,7 +12,7 @@ public class NationalityImpl implements Nationality {
|
||||
private static final long serialVersionUID = 238906193483424259L;
|
||||
private final String threeLetterIOCAcronym;
|
||||
|
||||
public NationalityImpl(String name, String threeLetterIOCAcronym) {
|
||||
public NationalityImpl(String threeLetterIOCAcronym) {
|
||||
if (threeLetterIOCAcronym.length() != 3) {
|
||||
throw new IllegalArgumentException("Three-letter IOC nationality acronym \""+threeLetterIOCAcronym+"\" doesn't have three letters.");
|
||||
}
|
||||
@@ -40,5 +42,10 @@ public class NationalityImpl implements Nationality {
|
||||
public CountryCode getCountryCode() {
|
||||
return CountryCodeFactory.INSTANCE.getFromThreeLetterIOCName(getThreeLetterIOCAcronym());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsManagedByDomainFactory resolve(DomainFactory domainFactory) {
|
||||
return domainFactory.getOrCreateNationality(getThreeLetterIOCAcronym());
|
||||
}
|
||||
|
||||
}
|
||||
-1
@@ -11,5 +11,4 @@ public class ObjectInputStreamResolvingAgainstDomainFactoryImpl extends ObjectIn
|
||||
throws IOException {
|
||||
super(in, domainFactory);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.Buoy;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
|
||||
public class WaypointImpl implements Waypoint {
|
||||
@@ -39,5 +40,15 @@ public class WaypointImpl implements Waypoint {
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint resolve(DomainFactory domainFactory) {
|
||||
Waypoint result = domainFactory.getExistingWaypointById(getId());
|
||||
if (result == null) {
|
||||
domainFactory.cacheWaypoint(this);
|
||||
result = this;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -2,6 +2,8 @@ package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.IsManagedByDomainFactory;
|
||||
import com.sap.sailing.domain.base.Team;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
@@ -50,6 +52,11 @@ public class DummyMarkPassingWithTimePointOnly implements MarkPassing {
|
||||
public Boat getBoat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsManagedByDomainFactory resolve(DomainFactory domainFactory) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user