/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jaid.ais;
import exception.InvalidPositionException;
import jaid.ais.data.ActiveTargetsMap;
import jaid.ais.data.Target;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.awt.Color;
import java.util.Random;
import nav.position.Position;
import settings.SettingsStore;
/**
* The data source manager forms the core part of JAID. It manages all receivers
* and their acquired targets.
*
* @author Benjamin Jakobus
* @version 1.0
* @since 1.0
*/
public class DataSourceManager {
/* The list of AIS sources used to connect to AIS servers. */
private List<DataSource> sources;
/* The instance of data manager in use by the system. Since only ever
* once instance of the receiver store can be used by the system, a singleton
* pattern is applied.
*/
private static DataSourceManager instance = null;
/* A map containing all targets identified by the receivers. */
private ActiveTargetsMap targetsMap;
/* Maps receiver rxIDs to their geographic position. */
private Map<String, Position> coordinates;
/**
* Constructs a new instance of <code>DataSourceManager</code>.
*
* @since 1.0
*/
private DataSourceManager() {
targetsMap = ActiveTargetsMap.getInstance();
sources = Collections.synchronizedList(new ArrayList<DataSource>(10));
coordinates = new ConcurrentHashMap<String, Position>(10);
}
/**
* Returns an instance of the data source manager. If no instance exists, a new
* one is generated.
*
* @return manager <code>DataSourceManager</code> object used to track
* targets.
* @since 1.0
*/
public static DataSourceManager getInstance() {
if (instance == null) {
instance = new DataSourceManager();
}
return instance;
}
/**
* Adds a new AIS source to the data source manager and assigns a default
* color to the source's coverage polygon.
*
* @param ipAddress The IP Address of the remote server that
* provides the AIS data.
* @param port The port on which the remote server listens to.
* @param rxID The remote server's rxID. The rxID string is
* used to identify the individual AIS source.
* @param latitude The latitude coordinate of the AIS source.
* @param longitude The longitude coordinate of the AIS source.
* @since 1.0
*/
public void addSource(String ipAddress, int port, String rxID,
double latitude, double longitude) {
try {
// Generate a random colour
Random rand = new Random();
int r, g, b;
r = rand.nextInt(255);
g = rand.nextInt(255);
b = rand.nextInt(255);
Position pos = new Position(latitude, longitude);
DataSource src = new DataSource(pos, rxID, ipAddress, port, true,
new Color(r, g, b, 50), targetsMap);
sources.add(src);
src.start();
coordinates.put(rxID, pos);
SettingsStore.getInstance().addDataSource(src);
} catch (InvalidPositionException e) {
e.printStackTrace();
}
}
public Target getTargetByMMSI(String mmsi) {
Target t = null;
for (DataSource s : sources) {
t = s.getTargetByMMSI(mmsi);
if (t != null) {
return t;
}
}
return t;
}
public Target getTargetByName(String name) {
Target t = null;
for (DataSource s : sources) {
t = s.getTargetByName(name);
if (t != null) {
return t;
}
}
return t;
}
/**
* Adds a new AIS source to the data source manager.
*
* @param ipAddress The IP Address of the remote server that
* provides the AIS data.
* @param port The port on which the remote server listens to.
* @param rxID The remote server's rxID. The rxID string is
* used to identify the individual AIS source.
* @param latitude The latitude coordinate of the AIS source.
* @param longitude The longitude coordinate of the AIS source.
* @param color The color that is to be associated with the
* source's coverage polygon.
* @since 1.0
*/
public void addSource(String ipAddress, int port, String rxID,
double latitude, double longitude, Color color) {
try {
Position pos = new Position(latitude, longitude);
DataSource src = new DataSource(pos, rxID, ipAddress, port, true, color, targetsMap);
sources.add(src);
coordinates.put(rxID, pos);
SettingsStore.getInstance().addDataSource(src);
} catch (InvalidPositionException e) {
e.printStackTrace();
}
}
/**
* Returns the position of receiver identified by rxID.
*
* @param rxID The rxID of the AIS source whose position we want.
* @return <code>Position</code> object defining the source's position
* in terms of latitude and longitude.
* @since 1.0
*/
public Position getPosition(String rxID) {
return coordinates.get(rxID);
}
/**
* Returns all targets acquired by all data sources.
*
* @return <code>Collection</code> containing all tracked targets.
* @since 1.0
*/
public Collection<Target> getTargets() {
return targetsMap.values();
}
/**
* Returns the map used to track active targets.
*
* @return The hash-map containing all active targets.
* @since 1.0
*/
public ActiveTargetsMap getActiveTargetsMap() {
return targetsMap;
}
/**
* Returns all targets identified by an individual source. The source is
* identified by its rxID.
*
* @param rxID The rxID of the source whose identified targets
* we want to fetch.
* @return <code>Collection</code> containing all targets that are
* currently being tracked by the AIS source that is being
* identified by the rxID string.
* @since 1.0
*/
public Collection<Target> getTargets(String rxID) {
Collection<Target> allTargets = targetsMap.values();
Collection<Target> targets = new ArrayList<Target>();
for (Target t : allTargets) {
if (rxID.equals(t.getSourceRxID())) {
targets.add(t);
}
}
return targets;
}
/**
* Retrieves all currently active AIS data sources.
*
* @return <code>List</code> containing all active AIS data sources.
* @since 1.0
*/
public List<DataSource> getSources() {
return sources;
}
/**
* Returns the target that matches the given MMSI..
*
* @param mmsi The MMSI used to identify the target.
* @return The <code>Target</code> that is identified by the given
* MMSI.
* @since 1.0
*/
public Target getTarget(String mmsi) {
return targetsMap.get(mmsi);
}
/**
* Enables or disables an AIS Source.
*
* @param enabled <code>True</code> if the source should be enabled;
* <code>false</code> if not.
* @param rxID The rxID of the source that you want to enable / disable.
*/
public void setSourceEnabled(boolean enabled, String rxID) {
for (DataSource dataSource : sources) {
if (dataSource.getRxID().compareTo(rxID) == 0) {
dataSource.setEnabled(enabled);
break;
}
}
}
/**
* Removes a AIS source and its associated targets from
* the manager and targets map.
*
* @param rxID The rxID of the AIS source that you want to remove.
* @since 1.0
*/
public void removeSource(String rxID) {
SettingsStore.getInstance().removeSource(rxID);
for (int i = 0; i < sources.size(); i++) {
if (sources.get(i).getRxID().compareTo(rxID) == 0) {
sources.get(i).setEnabled(false);
sources.remove(sources.get(i));
for (Target t : targetsMap.values()) {
if (t.getSourceRxID().compareTo(rxID) == 0) {
t.detach();
targetsMap.remove(t.getMMSI());
}
}
}
}
}
}