You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
5.4 KiB
178 lines
5.4 KiB
package shared.dataInput;
|
|
|
|
import org.w3c.dom.Element;
|
|
import org.w3c.dom.Node;
|
|
import shared.enums.XMLFileType;
|
|
import shared.exceptions.InvalidBoatDataException;
|
|
import shared.exceptions.XMLReaderException;
|
|
import shared.model.Boat;
|
|
import shared.model.GPSCoordinate;
|
|
import shared.model.Mark;
|
|
|
|
import java.io.InputStream;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Xml Reader class for Boat XML used for the race.
|
|
*/
|
|
public class BoatXMLReader extends XMLReader implements BoatDataSource {
|
|
|
|
/**
|
|
* A map of source ID to boat for all boats in the race.
|
|
*/
|
|
private final Map<Integer, Boat> boatMap = new HashMap<>();
|
|
|
|
/**
|
|
* A map of source ID to mark for all marks in the race.
|
|
*/
|
|
private final Map<Integer, Mark> markerMap = new HashMap<>();
|
|
|
|
|
|
/**
|
|
* Constructor for Boat XML using a file.
|
|
*
|
|
* @param file The file to read.
|
|
* @param type How to read the file - e.g., load as resource.
|
|
* @throws XMLReaderException Thrown if the file cannot be parsed.
|
|
* @throws InvalidBoatDataException Thrown if the file cannot be parsed correctly.
|
|
*/
|
|
public BoatXMLReader(String file, XMLFileType type) throws XMLReaderException, InvalidBoatDataException {
|
|
super(file, type);
|
|
|
|
//Attempt to read boat xml file.
|
|
try {
|
|
read();
|
|
} catch (Exception e) {
|
|
throw new InvalidBoatDataException("An error occurred while reading the boat xml file", e);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Constructor for Boat XML, using an InputStream.
|
|
*
|
|
* @param fileStream Stream to read boat data from.
|
|
* @throws XMLReaderException Thrown if the file cannot be parsed.
|
|
* @throws InvalidBoatDataException Thrown if the stream cannot be parsed correctly.
|
|
*/
|
|
public BoatXMLReader(InputStream fileStream) throws XMLReaderException, InvalidBoatDataException {
|
|
super(fileStream);
|
|
|
|
//Attempt to read boat xml stream.
|
|
try {
|
|
read();
|
|
} catch (Exception e) {
|
|
throw new InvalidBoatDataException("An error occurred while reading the boat xml stream", e);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Read the XML
|
|
*/
|
|
public void read() {
|
|
readSettings();
|
|
readShapes();
|
|
readBoats();
|
|
}
|
|
|
|
/**
|
|
* Read the Boats
|
|
*/
|
|
private void readBoats() {
|
|
Element nBoats = (Element) doc.getElementsByTagName("Boats").item(0);
|
|
for (int i = 0; i < nBoats.getChildNodes().getLength(); i++) {
|
|
Node boat = nBoats.getChildNodes().item(i);
|
|
if (boat.getNodeName().equals("Boat")) {
|
|
readBoatNode(boat);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ignored data
|
|
*/
|
|
private void readShapes() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Ignored data
|
|
*/
|
|
private void readSettings() {
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks if the node (XMl data node) is a Yacht or not
|
|
* @param boatNode Node from the XML
|
|
* @return Whether the node is a yacht node or not
|
|
*/
|
|
private boolean isYachtNode(Node boatNode) {
|
|
return boatNode.getAttributes().getNamedItem("Type").getTextContent().toLowerCase().equals("yacht");
|
|
}
|
|
|
|
/**
|
|
* Reads the information about one boat
|
|
* Ignored values: ShapeID, StoweName, HullNum, Skipper, Type
|
|
* @param boatNode The node representing a boat.
|
|
*/
|
|
private void readBoatNode(Node boatNode) {
|
|
int sourceID = Integer.parseInt(boatNode.getAttributes().getNamedItem("SourceID").getTextContent());
|
|
String name = boatNode.getAttributes().getNamedItem("BoatName").getTextContent();
|
|
|
|
if (isYachtNode(boatNode)) readYacht(boatNode, sourceID, name);
|
|
else readMark(boatNode, sourceID, name);
|
|
}
|
|
|
|
/**
|
|
* Read a Yacht Node
|
|
* @param boatNode Node to be read
|
|
* @param sourceID Source ID of the Yacht
|
|
* @param name Name of the Boat
|
|
*/
|
|
private void readYacht(Node boatNode, int sourceID, String name) {
|
|
String shortName = boatNode.getAttributes().getNamedItem("ShortName").getTextContent();
|
|
if (exists(boatNode, "Country")) {
|
|
String country = boatNode.getAttributes().getNamedItem("Country").getTextContent();
|
|
boatMap.put(sourceID, new Boat(sourceID, name, country));
|
|
} else {
|
|
boatMap.put(sourceID, new Boat(sourceID, name, shortName));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Read Marker Boats
|
|
* @param boatNode Node to be read
|
|
* @param sourceID Source ID of the boat
|
|
* @param name Name of the Marker Boat
|
|
*/
|
|
private void readMark(Node boatNode, int sourceID, String name) {
|
|
Node nCoord = ((Element)boatNode).getElementsByTagName("GPSposition").item(0);
|
|
double x = Double.parseDouble(nCoord.getAttributes().getNamedItem("X").getTextContent());
|
|
double y = Double.parseDouble(nCoord.getAttributes().getNamedItem("Y").getTextContent());
|
|
Mark mark = new Mark(sourceID, name, new GPSCoordinate(y,x));
|
|
markerMap.put(sourceID, mark);
|
|
}
|
|
|
|
/**
|
|
* Get the boats that are going to participate in this race
|
|
* @return Dictionary of boats that are to participate in this race indexed by SourceID
|
|
*/
|
|
@Override
|
|
public Map<Integer, Boat> getBoats() {
|
|
return boatMap;
|
|
}
|
|
|
|
/**
|
|
* Get the marker Boats that are participating in this race
|
|
* @return Dictionary of the Markers Boats that are in this race indexed by their Source ID.
|
|
*/
|
|
@Override
|
|
public Map<Integer, Mark> getMarkerBoats() {
|
|
return markerMap;
|
|
}
|
|
}
|