package org.lucci.madhoc.simulation;
import java.awt.Color;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import org.lucci.gui.ColorList;
import org.lucci.gui.Utilities;
import org.lucci.madhoc.gui.ProjectionComponent;
import org.lucci.madhoc.network.Application;
import org.lucci.madhoc.network.Network;
import org.lucci.madhoc.network.Station;
import org.lucci.madhoc.simulation.measure.DistributionSensor;
import org.lucci.madhoc.simulation.measure.MeasureHistory;
import org.lucci.madhoc.simulation.measure.NumericalSensor;
import org.lucci.madhoc.simulation.measure.Sensor;
import org.lucci.madhoc.simulation.projection.Projection;
public abstract class Monitor implements Configurable
{
private Map<Class, Sensor> sensorMap = new HashMap<Class, Sensor>();
private List<NumericalSensor> numericalMeasures;
private Collection<TerminationCondition> terminationConditions;
private Icon icon;
private Network network;
private Collection<Application> deployedApplications = new Vector<Application>();
private Class stationApplicationClass;
public Collection<Class> getMonitorViewClasses()
{
return new Vector<Class>();
}
public abstract String getName();
public abstract String getFriendlyName();
private final static ColorList colorList = new ColorList();
private Color color = null;
private MonitorInitializer initializer;
public boolean hasCompleted()
{
for (TerminationCondition tc : getTerminationConditions())
{
if (!tc.applicationHasCompleted(this))
{
return false;
}
}
return true;
}
public final Color getColor()
{
return this.color;
}
public void configure()
throws Throwable
{
setStationApplicationClass(getNetwork().getSimulation().getConfiguration().getClass(getName() + "_protocol_class"));
this.terminationConditions = (Collection<TerminationCondition>) getNetwork().getSimulation().getConfiguration().getInstantiatedClasses(getName() + "_termination_conditions");
for (TerminationCondition terminationCondition : this.terminationConditions)
{
terminationCondition.setMonitor(this);
terminationCondition.configure();
}
this.initializer = (MonitorInitializer) getNetwork().getSimulation().getConfiguration().getInstantiatedClass(getName() + "_initializer");
if (this.initializer != null)
{
this.initializer.setMonitor(this);
this.initializer.configure();
}
Collection<String> disableSensorsName = getNetwork().getSimulation().getConfiguration().getStrings(getName() + "_disabled_sensors");
for (Sensor sensor : new Vector<Sensor>(getSensorMap().values()))
{
if (!disableSensorsName.contains(sensor.getName()) && !disableSensorsName.contains(sensor.getClass().getName()))
{
for (Projection projection : getNetwork().getProjectionMap().values())
{
MeasureHistory history = sensor.createMeasureHistory();
history.setProjection(projection);
projection.getMeasureHistoryMap().put(sensor, history);
}
}
else
{
getSensorMap().remove(sensor.getClass());
}
}
int alpha = getNetwork().getSimulation().getConfiguration().getInteger("monitor_color_alpha");
this.color = Utilities.setAlpha(colorList.getNextColor(), alpha);
}
public void addMeasure(Sensor sensor)
{
sensor.setMonitor(this);
sensorMap.put(sensor.getClass(), sensor);
}
public Map<Class, Sensor> getSensorMap()
{
return sensorMap;
}
public Collection<NumericalSensor> getNumericalMeasures()
{
if (numericalMeasures == null)
{
numericalMeasures = new Vector<NumericalSensor>();
for (Sensor m : getSensorMap().values())
{
if (m instanceof NumericalSensor)
{
numericalMeasures.add((NumericalSensor) m);
}
}
}
return numericalMeasures;
}
public Collection<DistributionSensor> findDistributionMeasures()
{
Collection<DistributionSensor> distributionMeasures = new Vector<DistributionSensor>();
for (Sensor m : getSensorMap().values())
{
if (m instanceof DistributionSensor)
{
distributionMeasures.add((DistributionSensor) m);
}
}
return distributionMeasures;
}
public void deploy()
throws Throwable
{
if (getStationApplicationClass() == null)
throw new IllegalStateException("station application class is not defined, this method shouldn't be invoked");
for (Station computer : getNetwork().getStations())
{
Application stationApp = computer.deploy(getStationApplicationClass(), this);
stationApp.configure();
deployedApplications.add(stationApp);
}
}
public Icon getIcon()
{
if ( icon == null )
{
URL url = getClass().getResource("icon.png");
if (url == null)
{
url = ProjectionComponent.class.getResource("simulationApplicationDefaultIcon.png");
}
icon = new ImageIcon(url);
}
return icon;
}
public Collection<Application> findApplications(Collection<Station> computers)
{
Collection<Application> apps = new Vector<Application>();
for(Station computer : computers)
{
Application app = (Application) computer.getApplicationMap().getValue(getStationApplicationClass());
if (app != null)
{
apps.add(app);
}
}
return apps;
}
public Class getStationApplicationClass()
{
return stationApplicationClass;
}
public void setStationApplicationClass(Class stationApplicationClass)
{
this.stationApplicationClass = stationApplicationClass;
}
public abstract void resetIterationScopedValues();
public Network getNetwork()
{
return network;
}
public void setNetwork(Network network)
{
this.network = network;
}
public Collection<TerminationCondition> getTerminationConditions()
{
return terminationConditions;
}
public void setTerminationConditions(Collection<TerminationCondition> terminationCondition)
{
this.terminationConditions = terminationCondition;
}
public MonitorInitializer getInitializer()
{
return initializer;
}
public Collection<Application> getDeployedApplications()
{
return java.util.Collections.unmodifiableCollection(deployedApplications);
}
}