package arida.ufc.br.moap.datamodelapi.imp;
import arida.ufc.br.moap.core.algorithm.spi.ITrajectoryFactory;
import arida.ufc.br.moap.core.beans.MovingObject;
import arida.ufc.br.moap.core.beans.Trajectory;
import arida.ufc.br.moap.core.beans.TrajectoryFactoryImp;
import arida.ufc.br.moap.core.beans.iterators.api.IMovingObjectIterable;
import arida.ufc.br.moap.core.beans.iterators.api.ITrajectoryIterable;
import arida.ufc.br.moap.core.beans.iterators.imp.MovingObjectIterableImp;
import arida.ufc.br.moap.core.beans.iterators.imp.TrajectoryIterableImp;
import arida.ufc.br.moap.datamodelapi.spi.AbstractTrajectoryModel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* ITrajectoryModel implementation.
*
* @author franzejr
* @author rafaelelias
*/
public class TrajectoryModelImpl<S, T> extends AbstractTrajectoryModel<S, T> {
public TrajectoryModelImpl() {
super();
}
/*
* List of all trajectories. Remembering that a trajectory is a set of
* points which each point has a Latitude,Longitude and one Timestamp.
*/
/*
* Trajectory List
*/
private List<Trajectory<S, T>> trajectories = new ArrayList<Trajectory<S, T>>();
/*
* Identify a trajectory
*/
private HashMap<String, Trajectory<S, T>> trajectoryIndices = new HashMap<String, Trajectory<S, T>>();
/*
* Identify Moving Objects
*/
private HashMap<String, MovingObject> movingObjectIndices = new HashMap<String, MovingObject>();
/*
* Moving Object List
*/
private List<MovingObject> movingObjects = new ArrayList<MovingObject>();
/*
* Build a trajectory for a model
*/
private ITrajectoryFactory<S, T> factory = new TrajectoryFactoryImp<S, T>();
@Override
public Trajectory<S, T> getTrajectory(int id) {
if (Integer.valueOf(id) == null) {
throw new NullPointerException("Trajectory idx cannot be NULL");
}
return trajectories.get(id);
}
@Override
public ITrajectoryIterable<S, T> getTrajectories() {
ITrajectoryIterable<S, T> iterable = new TrajectoryIterableImp<S, T>(
trajectories, readWriteLock.readLock());
return iterable;
}
private void addMovingObject(MovingObject mo) {
if (mo == null) {
throw new NullPointerException("Moving object cannot be NULL");
}
if (!this.movingObjectIndices.containsKey(mo.getId())) {
this.movingObjects.add(mo);
this.movingObjectIndices.put(mo.getId(), mo);
}
}
@Override
public MovingObject getMovingObject(String id) {
return this.movingObjectIndices.get(id);
}
@Override
public int getTrajectoryCount() {
return this.trajectories.size();
}
@Override
public int getMovingObjectCount() {
return this.movingObjects.size();
}
@Override
public void addTrajectory(Trajectory<S, T> trajectory) {
if (trajectory == null) {
throw new IllegalArgumentException("trajectory cannot be NULL");
}
if (trajectory.getMovingObject() == null) {
throw new NullPointerException(
"Moving object for the trajectory cannot be NULL");
}
if (!this.trajectoryIndices.containsKey(trajectory.getId())) {
this.trajectories.add(trajectory);
this.trajectoryIndices.put(trajectory.getId(), trajectory);
addMovingObject(trajectory.getMovingObject());
}
}
@Override
public String toString() {
return "";
}
@Override
public ITrajectoryFactory<S, T> factory() {
return this.factory;
}
@Override
public MovingObject getMovingObject(int idx) {
if (Integer.valueOf(idx) == null) {
throw new IllegalArgumentException(
"Moving object idx cannot be NULL");
}
return this.movingObjects.get(idx);
}
@Override
public IMovingObjectIterable getMovingObjects() {
readLock();
return new MovingObjectIterableImp(movingObjects,
readWriteLock.readLock());
}
@Override
public Collection<Trajectory<S, T>> getTrajectories(MovingObject mo) {
if (mo == null) {
throw new IllegalArgumentException("mo id cannot be NULL");
}
List<Trajectory<S, T>> list = new ArrayList<Trajectory<S, T>>();
for (Trajectory<S, T> traj : this.trajectoryIndices.values()) {
if (traj.getMovingObject().equals(mo)) {
list.add(traj);
}
}
return list;
}
@Override
public Collection<Trajectory<S, T>> getTrajectories(String moId) {
if (moId == null) {
throw new IllegalArgumentException("mo id cannot be NULL");
}
MovingObject mo = this.movingObjectIndices.get(moId);
return getTrajectories(mo);
}
@Override
public Trajectory<S, T> getTrajectory(String id) {
if (id == null) {
throw new IllegalArgumentException("trajectory id cannot be NULL");
}
return this.trajectoryIndices.get(id);
}
@Override
public Trajectory<S, T> removeTrajectory(int id) {
if (Integer.valueOf(id) == null) {
throw new IllegalArgumentException("trajectory id cannot be NULL");
}
Trajectory<S, T> t = this.trajectories.remove(id);
if (t != null) {
this.trajectoryIndices.remove(t.getId());
}
return t;
}
@Override
public Trajectory<S, T> removeTrajectory(String id) {
if (id == null) {
throw new IllegalArgumentException("trajectory id cannot be NULL");
}
Trajectory<S, T> t = this.trajectoryIndices.remove(id);
if (t != null) {
this.trajectories.remove(t);
}
return t;
}
@Override
public MovingObject removeMovingObject(int idx) {
if (Integer.valueOf(idx) == null) {
throw new IllegalArgumentException("trajectory id cannot be NULL");
}
MovingObject mo = this.movingObjects.remove(idx);
if (mo != null) {
this.movingObjectIndices.remove(mo.getId());
/*
* Remove all the Moving Object's trajectories
*/
removeTrajectories(mo);
}
return mo;
}
@Override
public MovingObject removeMovingObject(String id) {
if (id == null) {
throw new IllegalArgumentException("trajectory id cannot be NULL");
}
MovingObject mo = this.movingObjectIndices.remove(id);
if (mo != null) {
this.movingObjects.remove(mo);
/*
* Remove all the Moving Object's trajectories
*/
removeTrajectories(mo);
}
return mo;
}
/*
* @return Remove all trajectories of a given {@link Moving Object}
*/
private void removeTrajectories(MovingObject mo) {
Collection<Trajectory<S, T>> c = getTrajectories(mo);
Iterator<Trajectory<S, T>> iter = c.iterator();
while (iter.hasNext()) {
this.trajectories.remove(iter.next());
}
}
public ReentrantReadWriteLock getReadWriteLock() {
return readWriteLock;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
this.factory = null;
this.movingObjectIndices = null;
this.movingObjects = null;
this.trajectories = null;
this.trajectoryIndices = null;
}
@Override
public String getName() {
return "Trajectory Model";
}
@Override
public Collection<Trajectory<S, T>> getInstances() {
return this.trajectories;
}
@Override
public void addInstance(Trajectory<S, T> instance) {
Trajectory<S, T> traj = (Trajectory<S, T>) instance;
this.addTrajectory(traj);
}
}