added observer pattern for Competitor, Team, Boat and Person

This commit is contained in:
Axel Uhl committed 2014-05-07 22:57:27 +02:00
1 parent ad4ce750c8
commit 7ca425d4a2
16 files changed
+428 -34

No files matched your search

@@ -0,0 +1,5 @@
package com.sap.sailing.domain.base;
public interface BoatChangeListener {
void sailIdChanged(String oldSailId, String newSailId);
}
@@ -10,4 +10,17 @@ public interface Competitor extends Named, WithID, IsManagedBySharedDomainFactor
Boat getBoat();
Color getColor();
/**
* Adds a listener to this competitor. The listener is also added to the boat and the team for changes.
* Adding a listener that is already part of this competitor's listeners set remains without effect.
*/
void addCompetitorChangeListener(CompetitorChangeListener listener);
/**
* Removes a listener from this competitor. The listener is also removed from the boat and the team.
* Trying to remove a listener that is not currently in the set of this competitor's listener remains
* without effect.
*/
void removeCompetitorChangeListener(CompetitorChangeListener listener);
}
@@ -0,0 +1,9 @@
package com.sap.sailing.domain.base;
import com.sap.sailing.domain.common.Color;
public interface CompetitorChangeListener extends BoatChangeListener, NationalityChangeListener {
void colorChanged(Color oldColor, Color newColor);
void nameChanged(String oldName, String newName);
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.base;
import java.io.Serializable;
public interface NationalityChangeListener extends Serializable {
void nationalityChanged(WithNationality what, Nationality oldNationality, Nationality newNationality);
}
@@ -1,17 +1,31 @@
package com.sap.sailing.domain.base.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.base.BoatChangeListener;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.common.impl.NamedImpl;
import com.sap.sailing.domain.common.impl.Util;
public class BoatImpl extends NamedImpl implements DynamicBoat {
private static final long serialVersionUID = 3489730487528955788L;
private final BoatClass boatClass;
private String sailID;
private transient Set<BoatChangeListener> listeners;
public BoatImpl(String name, BoatClass boatClass, String sailID) {
super(name);
this.boatClass = boatClass;
this.sailID = sailID;
this.listeners = new HashSet<BoatChangeListener>();
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
listeners = new HashSet<BoatChangeListener>();
}
@Override
@@ -26,6 +40,32 @@ public class BoatImpl extends NamedImpl implements DynamicBoat {
@Override
public void setSailId(String newSailId) {
this.sailID = newSailId;
final String oldSailId = this.sailID;
if (!Util.equalsWithNull(oldSailId, newSailId)) {
this.sailID = newSailId;
for (BoatChangeListener listener : getListeners()) {
listener.sailIdChanged(oldSailId, newSailId);
}
}
}
@Override
public void addBoatChangeListener(BoatChangeListener listener) {
synchronized (listeners) {
listeners.add(listener);
}
}
@Override
public void removeCompetitorChangeListener(BoatChangeListener listener) {
synchronized (listeners) {
listeners.remove(listener);
}
}
private Iterable<BoatChangeListener> getListeners() {
synchronized (listeners) {
return new HashSet<BoatChangeListener>(listeners);
}
}
}
@@ -1,10 +1,16 @@
package com.sap.sailing.domain.base.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorChangeListener;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.common.Color;
import com.sap.sailing.domain.common.impl.Util;
public class CompetitorImpl implements DynamicCompetitor {
private static final long serialVersionUID = 294603681016643157L;
@@ -12,8 +18,8 @@ public class CompetitorImpl implements DynamicCompetitor {
private final DynamicBoat boat;
private final Serializable id;
private String name;
private Color color;
private transient Set<CompetitorChangeListener> listeners;
public CompetitorImpl(Serializable id, String name, Color color, DynamicTeam team, DynamicBoat boat) {
this.id = id;
@@ -21,6 +27,12 @@ public class CompetitorImpl implements DynamicCompetitor {
this.team = team;
this.boat = boat;
this.color = color;
this.listeners = new HashSet<CompetitorChangeListener>();
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
listeners = new HashSet<CompetitorChangeListener>();
}
@Override
@@ -35,7 +47,13 @@ public class CompetitorImpl implements DynamicCompetitor {
@Override
public void setName(String newName) {
this.name = newName;
final String oldName = this.name;
if (!Util.equalsWithNull(oldName, newName)) {
this.name = newName;
for (CompetitorChangeListener listener : getListeners()) {
listener.nameChanged(oldName, newName);
}
}
}
@Override
@@ -64,6 +82,36 @@ public class CompetitorImpl implements DynamicCompetitor {
}
public void setColor(Color color) {
this.color = color;
final Color oldColor = this.color;
if (!Util.equalsWithNull(oldColor, color)) {
this.color = color;
for (CompetitorChangeListener listener : getListeners()) {
listener.colorChanged(oldColor, color);
}
}
}
@Override
public void addCompetitorChangeListener(CompetitorChangeListener listener) {
synchronized (listeners) {
listeners.add(listener);
}
getBoat().addBoatChangeListener(listener);
getTeam().addNationalityChangeListener(listener);
}
@Override
public void removeCompetitorChangeListener(CompetitorChangeListener listener) {
synchronized (listeners) {
listeners.remove(listener);
}
getBoat().removeCompetitorChangeListener(listener);
getTeam().removeNationalityChangeListener(listener);
}
private Iterable<CompetitorChangeListener> getListeners() {
synchronized (listeners) {
return new HashSet<CompetitorChangeListener>(listeners);
}
}
}
@@ -1,7 +1,13 @@
package com.sap.sailing.domain.base.impl;
import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.base.BoatChangeListener;
public interface DynamicBoat extends Boat {
void setSailId(String newSailId);
void addBoatChangeListener(BoatChangeListener listener);
void removeCompetitorChangeListener(BoatChangeListener listener);
}
@@ -1,8 +1,13 @@
package com.sap.sailing.domain.base.impl;
import com.sap.sailing.domain.base.Nationality;
import com.sap.sailing.domain.base.NationalityChangeListener;
import com.sap.sailing.domain.base.Person;
public interface DynamicPerson extends Person {
void setNationality(Nationality newNationality);
void addNationalityChangeListener(NationalityChangeListener listener);
void removeNationalityChangeListener(NationalityChangeListener listener);
}
@@ -1,8 +1,13 @@
package com.sap.sailing.domain.base.impl;
import com.sap.sailing.domain.base.Nationality;
import com.sap.sailing.domain.base.NationalityChangeListener;
import com.sap.sailing.domain.base.Team;
public interface DynamicTeam extends Team {
void setNationality(Nationality newNationality);
void addNationalityChangeListener(NationalityChangeListener listener);
void removeNationalityChangeListener(NationalityChangeListener listener);
}
@@ -2,21 +2,27 @@ package com.sap.sailing.domain.base.impl;
import java.io.InputStream;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.base.Nationality;
import com.sap.sailing.domain.base.NationalityChangeListener;
import com.sap.sailing.domain.common.impl.NamedImpl;
import com.sap.sailing.domain.common.impl.Util;
public class PersonImpl extends NamedImpl implements DynamicPerson {
private static final long serialVersionUID = -2104903799224233508L;
private Nationality nationality;
private final Date dateOfBirth;
private final String description;
private transient Set<NationalityChangeListener> listeners;
public PersonImpl(String name, Nationality nationality, Date dateOfBirth, String description) {
super(name);
this.nationality = nationality;
this.dateOfBirth = dateOfBirth;
this.description = description;
this.listeners = new HashSet<NationalityChangeListener>();
}
@Override
@@ -31,7 +37,13 @@ public class PersonImpl extends NamedImpl implements DynamicPerson {
@Override
public void setNationality(Nationality newNationality) {
this.nationality = newNationality;
final Nationality oldNationality = this.nationality;
if (!Util.equalsWithNull(oldNationality, newNationality)) {
this.nationality = newNationality;
for (NationalityChangeListener listener : getListeners()) {
listener.nationalityChanged(this, oldNationality, newNationality);
}
}
}
@Override
@@ -44,4 +56,23 @@ public class PersonImpl extends NamedImpl implements DynamicPerson {
return description;
}
@Override
public void addNationalityChangeListener(NationalityChangeListener listener) {
synchronized (listeners) {
listeners.add(listener);
}
}
@Override
public void removeNationalityChangeListener(NationalityChangeListener listener) {
synchronized (listeners) {
listeners.remove(listener);
}
}
private Iterable<NationalityChangeListener> getListeners() {
synchronized (listeners) {
return new HashSet<NationalityChangeListener>(listeners);
}
}
}
@@ -1,18 +1,80 @@
package com.sap.sailing.domain.base.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.base.Nationality;
import com.sap.sailing.domain.base.NationalityChangeListener;
import com.sap.sailing.domain.base.Person;
import com.sap.sailing.domain.base.WithNationality;
import com.sap.sailing.domain.common.impl.NamedImpl;
import com.sap.sailing.domain.common.impl.Util;
public class TeamImpl extends NamedImpl implements DynamicTeam {
private static final long serialVersionUID = 4646922280429210183L;
private final Iterable<? extends DynamicPerson> sailors;
private final Person coach;
private final DynamicPerson coach;
private final NationalityChangeListener personNationalityChangeForwarder;
private transient Set<NationalityChangeListener> listeners;
public TeamImpl(String name, Iterable<? extends DynamicPerson> sailors, Person coach) {
public TeamImpl(String name, Iterable<? extends DynamicPerson> sailors, DynamicPerson coach) {
super(name);
listeners = new HashSet<NationalityChangeListener>();
this.sailors = sailors;
this.coach = coach;
this.personNationalityChangeForwarder = new NationalityChangeListener() {
private static final long serialVersionUID = -6024941913105410444L;
@Override
public void nationalityChanged(WithNationality what, Nationality oldNationality, Nationality newNationality) {
if (what == getNationalityDonor()) {
for (NationalityChangeListener listener : getNationalityChangeListeners()) {
listener.nationalityChanged(TeamImpl.this, oldNationality, newNationality);
}
}
}
};
setTransitiveListeners();
}
/**
* The listeners on {@link DynamicPerson} are transient. Our {@link #personNationalityChangeForwarder} needs to
* be restored after deserialization.
*/
private void setTransitiveListeners() {
if (this.sailors != null) {
for (DynamicPerson sailor : this.sailors) {
sailor.addNationalityChangeListener(personNationalityChangeForwarder);
}
}
if (this.coach != null) {
this.coach.addNationalityChangeListener(personNationalityChangeForwarder);
}
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
listeners = new HashSet<NationalityChangeListener>();
setTransitiveListeners();
}
public void addNationalityChangeListener(NationalityChangeListener listener) {
synchronized (listeners) {
listeners.add(listener);
}
}
public void removeNationalityChangeListener(NationalityChangeListener listener) {
synchronized (listeners) {
listeners.remove(listener);
}
}
private Iterable<NationalityChangeListener> getNationalityChangeListeners() {
synchronized (listeners) {
return new HashSet<NationalityChangeListener>(listeners);
}
}
@Override
@@ -21,28 +83,38 @@ public class TeamImpl extends NamedImpl implements DynamicTeam {
}
@Override
public Person getCoach() {
public DynamicPerson getCoach() {
return coach;
}
@Override
public Nationality getNationality() {
return getNationalityDonor().getNationality();
}
private WithNationality getNationalityDonor() {
for (Person sailor : getSailors()) {
if (sailor.getNationality() != null) {
return sailor.getNationality();
return sailor;
}
}
if (getCoach() != null) {
return getCoach().getNationality();
return getCoach();
}
return null;
}
@Override
public void setNationality(Nationality newNationality) {
for (Person sailor : getSailors()) {
((DynamicPerson) sailor).setNationality(newNationality);
Nationality oldNationality = getNationality();
if (!Util.equalsWithNull(oldNationality, newNationality)) {
for (Person sailor : getSailors()) {
((DynamicPerson) sailor).setNationality(newNationality);
}
for (NationalityChangeListener listener : getNationalityChangeListeners()) {
listener.nationalityChanged(this, oldNationality, newNationality);
}
}
}
}