package classes;
import enums.TrafficDefinitionLayerType;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import roadnetwork.RoadNetwork;
import roadnetwork.RoadNetworkParser;
import simulation.JobType;
import simulation.Simulation;
import simulation.VehicleType;
import tdl.XMLHelpers;
import trafficdefinition.ActivityBasedTrafficDefinitionLayer;
import trafficdefinition.RandomTrafficDefinitionLayer;
import trafficdefinition.TrafficDefinitionLayer;
import trafficdefinition.UserDefinedTrafficDefinitionLayer;
/**
* Class representing a simulation project. The project's most basic elements are a road network and a list of traffic definition layers.
*/
public class Project {
/**
* Static field containing the currently loaded project
*/
private transient static Project currentlyLoadedProject = null;
/**
* Static method that returns the currently loaded project.
* @return the currently loaded project
* @uml.property name="currentlyLoadedProject"
*/
public static Project getCurrentlyLoadedProject() {
return currentlyLoadedProject;
}
/**
* The default job type
*/
private JobType defaultJobType = null;
/**
* The default vehicle type
*/
private VehicleType defaultVehicleType = null;
/**
* The project's file name.
*/
private String fileName = null;
/**
* The list of job types.
*/
private List<JobType> jobTypes = null;
/**
* The road network (map).
*/
private RoadNetwork roadNetwork = null;
/**
* The list of traffic definition layers.
*/
private List<TrafficDefinitionLayer> trafficLayers = null;
/**
* The list of vehicle types.
*/
private List<VehicleType> vehicleTypes = null;
/**
* The vehicle selection for the activity-based traffic layers.
* @uml.property name="activityBasedTrafficVehicleSelection"
* @uml.associationEnd
*/
private TypeSelection<VehicleType> activityBasedTrafficVehicleSelection;
/**
* The project's simulation
*/
private Simulation simulation = new Simulation();
/**
* Constructor for opening a project from a file
*
* @param projectPath
* The path to the file containing the project
* @throws Exception
* If an error has occured during the project opening process.
*/
public Project(String projectPath) throws Exception {
// Set the project's file name
fileName = projectPath;
// Create the input streams to read the project from the file
FileInputStream fileIn = new FileInputStream(fileName);
ObjectInputStream in = new ObjectInputStream(fileIn);
// Read the road network
roadNetwork = (RoadNetwork) in.readObject();
// Read the traffic definition layers
trafficLayers = (ArrayList<TrafficDefinitionLayer>) in.readObject();
// Read the simulation
simulation = (Simulation) in.readObject();
// Read the job and vehicle types
jobTypes = (ArrayList<JobType>) in.readObject();
vehicleTypes = (ArrayList<VehicleType>) in.readObject();
defaultJobType = (JobType) in.readObject();
defaultVehicleType = (VehicleType) in.readObject();
// Read the vehicle selection for the activity-based layers
activityBasedTrafficVehicleSelection = (TypeSelection<VehicleType>) in.readObject();
in.close();
// Set the static currently loaded project variable
Project.currentlyLoadedProject = this;
}
/**
* Constructor for creating a new project.
*
* @param projectPath
* The path to the file that the project will be saved to.
* @param roadNetworkFile
* The file containing the road network.
* @throws Exception
* If an error has occured during the project creation process.
*/
public Project(String projectPath, File roadNetworkFile) throws Exception {
// Set the static currently loaded project variable
Project.currentlyLoadedProject = this;
// Parse the road network xml file
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document roadNetworkXMLDocument = parser.parse(roadNetworkFile);
roadNetwork = (new RoadNetworkParser()).ParseXMLNetFile(roadNetworkXMLDocument);
// Initialize the layers
trafficLayers = new ArrayList<TrafficDefinitionLayer>();
// Create the job types array and add the default type
jobTypes = new ArrayList<JobType>();
defaultJobType = JobType.CreateDefaultType();
jobTypes.add(defaultJobType);
// Create the vehicle types array and add the default type
vehicleTypes = new ArrayList<VehicleType>();
defaultVehicleType = VehicleType.CreateDefaultType();
vehicleTypes.add(defaultVehicleType);
// Add the default vehicle to the activity-based layers vehicle
// selection
activityBasedTrafficVehicleSelection = new TypeSelection<VehicleType>();
activityBasedTrafficVehicleSelection.add(new Pair<VehicleType, Float>(defaultVehicleType, 1.f));
// Create a default user defined traffic definition layer
createNewLayer(TrafficDefinitionLayerType.UserDefined);
// Set the project's file name
fileName = projectPath;
// Create the output streams to write the project to file
FileOutputStream fileOut = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
// Read the edges and nodes files
File edgesFile = new File(roadNetworkFile.getAbsolutePath().replaceFirst(".net.", ".edg."));
File nodesFile = new File(roadNetworkFile.getAbsolutePath().replaceFirst(".net.", ".nod."));
FileInputStream fileInEdges = new FileInputStream(edgesFile);
FileInputStream fileInNodes = new FileInputStream(nodesFile);
byte[] edgeBytes = new byte[(int) edgesFile.length()];
byte[] nodeBytes = new byte[(int) nodesFile.length()];
fileInEdges.read(edgeBytes);
fileInNodes.read(nodeBytes);
// Save the contents of the edges and nodes files in the road network
roadNetwork.setRoadNetworkEdgesXML(new String(edgeBytes));
roadNetwork.setRoadNetworkNodesXML(new String(nodeBytes));
// Write the project
out.writeObject(roadNetwork);
out.writeObject(trafficLayers);
out.writeObject(simulation);
out.writeObject(jobTypes);
out.writeObject(vehicleTypes);
out.writeObject(defaultJobType);
out.writeObject(defaultVehicleType);
out.writeObject(activityBasedTrafficVehicleSelection);
out.close();
}
/**
* Closes the project (sets the currently loaded project to null)
*
*/
public void Close() {
// Set the static currently loaded project variable
Project.currentlyLoadedProject = null;
}
/**
* Creates a new {@link TrafficDefinitionLayer} that is a copy of the source
* layer and adds it to the project. The project is automatically registered
* as a listener to be notified when the new layer is modified so that it
* knows when it needs to be saved (see the {@link #dirty field}).
*
* @param source
* The layer to be copied.
* @return The newly created layer.
*/
public TrafficDefinitionLayer createDuplicateLayer(TrafficDefinitionLayer source) {
TrafficDefinitionLayer newLayer = source.duplicate();
trafficLayers.add(newLayer);
return newLayer;
}
/**
* Creates a new {@link TrafficDefinitionLayer} and adds it to the project.
*
* @param type
* The type of the new layer
* @return The newly created layer.
*/
public TrafficDefinitionLayer createNewLayer(TrafficDefinitionLayerType type) {
TrafficDefinitionLayer newLayer = null;
switch (type) {
case UserDefined:
newLayer = new UserDefinedTrafficDefinitionLayer();
break;
case ActivityBased:
newLayer = new ActivityBasedTrafficDefinitionLayer();
break;
case Random:
newLayer = new RandomTrafficDefinitionLayer();
break;
}
trafficLayers.add(newLayer);
return newLayer;
}
/**
* Removes the layer specified from the project's traffic layers collection.
*
* @param layer
* The layer to delete.
*/
public void DeleteLayer(TrafficDefinitionLayer layer) {
trafficLayers.remove(layer);
}
/**
* Returns the default job type
* @return the default job type
* @uml.property name="defaultJobType"
*/
public JobType getDefaultJobType() {
return defaultJobType;
}
/**
* Returns the default vehicle type
* @return the default vehicle type
* @uml.property name="defaultVehicleType"
*/
public VehicleType getDefaultVehicleType() {
return defaultVehicleType;
}
/**
* Gets the project's file name
* @return
* @uml.property name="fileName"
*/
public String getFileName() {
return fileName;
}
/**
* Gets the project's job types
* @return
* @uml.property name="jobTypes"
*/
public List<JobType> getJobTypes() {
return jobTypes;
}
/**
* Gets the {@link TrafficDefinitionLayer} with the specified index.
*
* @param index
* @return
*/
public TrafficDefinitionLayer getLayer(int index) {
return trafficLayers.get(index);
}
/**
* Gets the project's road network.
* @return
* @uml.property name="roadNetwork"
*/
public RoadNetwork getRoadNetwork() {
return roadNetwork;
}
/**
* Gets the project's traffic definition layers
* @return
* @uml.property name="trafficLayers"
*/
public List<TrafficDefinitionLayer> getTrafficLayers() {
return trafficLayers;
}
/**
* Returns the project's vehicle types
* @return
* @uml.property name="vehicleTypes"
*/
public List<VehicleType> getVehicleTypes() {
return vehicleTypes;
}
/**
* Exports the traffic definition project in TDL format
* @param path the path to the file name to export
*/
public void saveTDL(String path) throws Exception {
FileWriter fw = new FileWriter(path);
PrintWriter pw = new PrintWriter(fw);
pw.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
pw.println("<trafficModel name =\"" + simulation.getName() + "\" startingTime =\"" + String.valueOf(simulation.getBeginTime()) + "\" endingTime =\"" + String.valueOf(simulation.getEndTime()) + "\" xmlns=\"http://tempuri.org/TDL.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" >");
pw.println("<jobTypes>");
for (JobType j : jobTypes) {
pw.println("<job name=\"" + j.getName() + "\" startingTime=\"" + String.valueOf(j.getStartingTime()) + "\" endingTime=\"" + String.valueOf(j.getEndingTime()) + "\"/>");
}
pw.println("</jobTypes>");
pw.println("<vehicleTypes>");
for (VehicleType v : vehicleTypes) {
pw.println("<vehicle name=\"" + v.getName() + "\" acceleration=\"" + String.valueOf(v.getAcceleration()) + "\" deceleration=\"" + String.valueOf(v.getDeceleration()) + "\" length=\"" + String.valueOf(v.getLength()) + "\" maximumSpeed=\"" + String.valueOf(v.getMaximumSpeed()) + "\" driverImperfection=\"" + String.valueOf(v.getDriverImperfection()) + "\" />");
}
pw.println("</vehicleTypes>");
pw.print(XMLHelpers.vehicleSelectionToXML("activityBasedTrafficVehicleSelection", activityBasedTrafficVehicleSelection));
pw.println("<trafficLayers>");
for (TrafficDefinitionLayer tdl : trafficLayers) {
pw.print(tdl.toXML());
}
pw.println("</trafficLayers>");
pw.println("</trafficModel>");
pw.close();
fw.close();
}
/**
* Saves the project to the file specified by the {@link #fileName} field
*
* @throws Exception
* If an error occurs during the project saving process.
*/
public void Save() throws Exception {
// Create the output streams used for saving the project
FileOutputStream fileOut = new FileOutputStream(fileName, false);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
// Write the project elements
out.writeObject(roadNetwork);
out.writeObject(trafficLayers);
out.writeObject(simulation);
out.writeObject(jobTypes);
out.writeObject(vehicleTypes);
out.writeObject(defaultJobType);
out.writeObject(defaultVehicleType);
out.writeObject(activityBasedTrafficVehicleSelection);
out.close();
}
/**
* Saves the project to the file specified and sets the project's
* {@link #fileName} to the specified path.
*
* @param path
* The path to the file that the project will be saved to.
* @throws Exception
* If an error has occured during the project saving process.
*/
public void SaveAs(String path) throws Exception {
fileName = path;
Save();
}
/**
* Sets the project's job types
* @param jobTypes
* @uml.property name="jobTypes"
*/
public void setJobTypes(List<JobType> jobTypes) {
this.jobTypes = jobTypes;
}
/**
* Sets the project's vehicle types
* @param vehicleTypes
* @uml.property name="vehicleTypes"
*/
public void setVehicleTypes(List<VehicleType> vehicleTypes) {
this.vehicleTypes = vehicleTypes;
}
/**
* Returns the project's simulation
* @return
* @uml.property name="simulation"
*/
public Simulation getSimulation() {
return simulation;
}
/**
* Returns the vehicle selection for the activity based layers
* @return
* @uml.property name="activityBasedTrafficVehicleSelection"
*/
public TypeSelection<VehicleType> getActivityBasedTrafficVehicleSelection() {
return activityBasedTrafficVehicleSelection;
}
/**
* Sets the vehicle selection for the activity-based layers
* @param vehicleSelection
* @uml.property name="activityBasedTrafficVehicleSelection"
*/
public void setActivityBasedTrafficVehicleSelection(TypeSelection<VehicleType> vehicleSelection) {
this.activityBasedTrafficVehicleSelection = vehicleSelection;
}
}