209 lines
8.3 KiB
Java
209 lines
8.3 KiB
Java
package configuration;
|
|
|
|
import metadata.*;
|
|
import org.w3c.dom.Document;
|
|
import org.w3c.dom.Element;
|
|
import org.w3c.dom.Node;
|
|
import org.xml.sax.SAXException;
|
|
import simulation.*;
|
|
|
|
import javax.xml.parsers.DocumentBuilder;
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
public class XmlConfigurationParser implements ConfigurationParser {
|
|
public static final String TAG_METADATA = "metadonnees";
|
|
public static final String TAG_SIMULATION_DATA = "simulation";
|
|
public static final String TAG_BUILDING = "usine";
|
|
public static final String TAG_ROUTES = "chemins";
|
|
public static final String TAG_ICONS = "icones";
|
|
public static final String TAG_INPUT = "entree";
|
|
public static final String TAG_OUTPUT = "sortie";
|
|
public static final String TAG_PRODUCTION_INTERVAL = "interval-production";
|
|
public static final String ATTRIBUTE_TYPE = "type";
|
|
public static final String ATTRIBUTE_PATH = "path";
|
|
public static final String ATTRIBUTE_QUANTITY = "quantite";
|
|
public static final String ATTRIBUTE_CAPACITY = "capacite";
|
|
public static final String ATTRIBUTE_ID = "id";
|
|
public static final String ATTRIBUTE_X = "x";
|
|
public static final String ATTRIBUTE_Y = "y";
|
|
public static final String ATTRIBUTE_FROM = "de";
|
|
public static final String ATTRIBUTE_TO = "vers";
|
|
|
|
@Override
|
|
public SimulationConfiguration parseConfiguration(File file) throws ConfigurationParsingException {
|
|
Document document = parseDocument(file);
|
|
|
|
Map<String, BuildingMetadata> buildingsMetadata = parseBuildingsMetadata(document);
|
|
SimulationData simulationData = parseSimulationData(document, buildingsMetadata);
|
|
|
|
return new SimulationConfiguration(buildingsMetadata, simulationData);
|
|
}
|
|
|
|
private Document parseDocument(File file) throws ConfigurationParsingException {
|
|
try {
|
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
|
|
Document document = builder.parse(file);
|
|
document.getDocumentElement().normalize();
|
|
|
|
return document;
|
|
} catch (ParserConfigurationException | IOException | SAXException e) {
|
|
throw new ConfigurationParsingException("La lecture du fichier a échoué", e);
|
|
}
|
|
}
|
|
|
|
private Map<String, BuildingMetadata> parseBuildingsMetadata(Document document) {
|
|
Node metadataNode = document.getElementsByTagName(TAG_METADATA).item(0);
|
|
Map<String, BuildingMetadata> metadata = new HashMap<>();
|
|
|
|
for (Element elem : new IterableElementList(metadataNode.getChildNodes())) {
|
|
String buildingType = elem.getAttribute(ATTRIBUTE_TYPE);
|
|
|
|
metadata.put(buildingType, parseBuildingMetadata(elem));
|
|
}
|
|
|
|
return metadata;
|
|
}
|
|
|
|
private BuildingMetadata parseBuildingMetadata(Element buildingElement) {
|
|
String type = buildingElement.getAttribute(ATTRIBUTE_TYPE);
|
|
|
|
return type.equals(BuildingMetadata.TYPE_WAREHOUSE) ?
|
|
parseWarehouseMetadata(buildingElement, type) :
|
|
parseFactoryMetadata(buildingElement, type);
|
|
}
|
|
|
|
private BuildingMetadata parseFactoryMetadata(Element factoryElement, String type) {
|
|
Map<BuildingState, String> iconsPaths = null;
|
|
Collection<FactoryInput> inputs = new ArrayList<>();
|
|
FactoryOutput output = null;
|
|
int productionInterval = -1;
|
|
|
|
for (Element elem : new IterableElementList(factoryElement.getChildNodes())) {
|
|
switch (elem.getNodeName()) {
|
|
case TAG_ICONS -> iconsPaths = parseBuildingIcons(elem);
|
|
case TAG_INPUT -> {
|
|
FactoryInput input = parseFactoryInput(elem);
|
|
inputs.add(input);
|
|
}
|
|
case TAG_OUTPUT -> output = parseFactoryOutput(elem);
|
|
case TAG_PRODUCTION_INTERVAL -> productionInterval = Integer.parseInt(elem.getTextContent());
|
|
}
|
|
}
|
|
|
|
return new FactoryMetadata(type, iconsPaths, productionInterval, inputs, output);
|
|
}
|
|
|
|
private BuildingMetadata parseWarehouseMetadata(Element warehouseElement, String type) {
|
|
Map<BuildingState, String> iconsPaths = null;
|
|
WarehouseInput input = null;
|
|
|
|
for (Element elem : new IterableElementList(warehouseElement.getChildNodes())) {
|
|
switch (elem.getNodeName()) {
|
|
case TAG_ICONS -> iconsPaths = parseBuildingIcons(elem);
|
|
case TAG_INPUT -> input = parseWarehouseInput(elem);
|
|
}
|
|
}
|
|
|
|
return new WarehouseMetadata(type, iconsPaths, input);
|
|
}
|
|
|
|
private Map<BuildingState, String> parseBuildingIcons(Element iconsElement) {
|
|
Map<BuildingState, String> iconsPaths = new HashMap<>();
|
|
|
|
for (Element elem : new IterableElementList(iconsElement.getChildNodes())) {
|
|
BuildingState state = BuildingState.getFromTypeName(elem.getAttribute(ATTRIBUTE_TYPE));
|
|
String path = elem.getAttribute(ATTRIBUTE_PATH);
|
|
|
|
iconsPaths.put(state, path);
|
|
}
|
|
|
|
return iconsPaths;
|
|
}
|
|
|
|
private FactoryInput parseFactoryInput(Element inputElement) {
|
|
ComponentType type = ComponentType.getForTypeName(inputElement.getAttribute(ATTRIBUTE_TYPE));
|
|
int quantity = Integer.parseInt(inputElement.getAttribute(ATTRIBUTE_QUANTITY));
|
|
|
|
return new FactoryInput(type, quantity);
|
|
}
|
|
|
|
private WarehouseInput parseWarehouseInput(Element inputElement) {
|
|
ComponentType type = ComponentType.getForTypeName(inputElement.getAttribute(ATTRIBUTE_TYPE));
|
|
int capacity = Integer.parseInt(inputElement.getAttribute(ATTRIBUTE_CAPACITY));
|
|
|
|
return new WarehouseInput(type, capacity);
|
|
}
|
|
|
|
private FactoryOutput parseFactoryOutput(Element outputElement) {
|
|
ComponentType type = ComponentType.getForTypeName(outputElement.getAttribute(ATTRIBUTE_TYPE));
|
|
|
|
return new FactoryOutput(type);
|
|
}
|
|
|
|
private SimulationData parseSimulationData(Document document, Map<String, BuildingMetadata> buildingMetadata) {
|
|
Node dataNode = document.getElementsByTagName(TAG_SIMULATION_DATA).item(0);
|
|
|
|
Collection<Building> buildings = new ArrayList<>();
|
|
Collection<Route> routes = null;
|
|
|
|
for (Element elem : new IterableElementList(dataNode.getChildNodes())) {
|
|
switch (elem.getNodeName()) {
|
|
case TAG_BUILDING -> buildings.add(parseBuilding(elem, buildingMetadata));
|
|
case TAG_ROUTES -> routes = parseRoutes(elem);
|
|
}
|
|
}
|
|
|
|
subscribeFactories(buildings);
|
|
return new SimulationData(buildings, routes);
|
|
}
|
|
|
|
private void subscribeFactories(Collection<Building> buildings) {
|
|
Warehouse warehouse = (Warehouse) buildings.stream()
|
|
.filter(b -> b.getType().equals(BuildingMetadata.TYPE_WAREHOUSE))
|
|
.findFirst().get();
|
|
|
|
for (Building building : buildings) {
|
|
if (!(building instanceof Factory)) {
|
|
continue;
|
|
}
|
|
|
|
warehouse.attach(((Factory) building));
|
|
}
|
|
}
|
|
|
|
private Building parseBuilding(Element buildingElement, Map<String, BuildingMetadata> buildingMetadata) {
|
|
String type = buildingElement.getAttribute(ATTRIBUTE_TYPE);
|
|
int id = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_ID));
|
|
int x = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_X));
|
|
int y = Integer.parseInt(buildingElement.getAttribute(ATTRIBUTE_Y));
|
|
|
|
BuildingMetadata metadata = buildingMetadata.get(type);
|
|
|
|
return type.equals(BuildingMetadata.TYPE_WAREHOUSE) ?
|
|
new Warehouse(id, type, x, y, (WarehouseMetadata) metadata) :
|
|
new Factory(id, type, x, y, (FactoryMetadata) metadata);
|
|
}
|
|
|
|
private Collection<Route> parseRoutes(Element routesElement) {
|
|
Collection<Route> routes = new ArrayList<>();
|
|
|
|
for (Element elem : new IterableElementList(routesElement.getChildNodes())) {
|
|
int from = Integer.parseInt(elem.getAttribute(ATTRIBUTE_FROM));
|
|
int to = Integer.parseInt(elem.getAttribute(ATTRIBUTE_TO));
|
|
|
|
routes.add(new Route(from, to));
|
|
}
|
|
|
|
return routes;
|
|
}
|
|
}
|