mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Moved XML parsing to non static class to create objects. Changed the abstraction as using generics in maps lead to more headaches than anything. Still not quite completed. Needs documentation and validation for tags too.
#story[820]
This commit is contained in:
@@ -129,7 +129,7 @@ public class StreamParser {
|
||||
while (payloadStream.available() > 0 && (currentChar = payloadStream.read()) != 0) {
|
||||
xmlMessage += (char)currentChar;
|
||||
}
|
||||
if (xmlMessageSubType == 6) System.out.println(xmlMessage);
|
||||
if (xmlMessageSubType == 7) System.out.println(xmlMessage);
|
||||
|
||||
//Create XML document Object
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
@@ -137,183 +137,13 @@ public class StreamParser {
|
||||
try {
|
||||
db = dbf.newDocumentBuilder();
|
||||
Document doc = db.parse(new InputSource(new StringReader(xmlMessage)));
|
||||
switch(xmlMessageSubType) {
|
||||
case 5: parseRegattaXML(doc);
|
||||
case 6: parseRaceXML(doc);
|
||||
case 7: parseBoatXML(doc);
|
||||
if (xmlMessageSubType == 7) {
|
||||
XMLParser x = new XMLParser();
|
||||
XMLParser.BoatXMLObject xr = x.createBoatXML(doc);
|
||||
}
|
||||
|
||||
} catch (ParserConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SAXException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
} catch (ParserConfigurationException|SAXException|IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void parseRegattaXML(Document doc) {
|
||||
Element docEle = doc.getDocumentElement();
|
||||
String[] regattaElements = {"RegattaID", "RegattaName", "CourseName", "CentralLatitude", "CentralLongitude",
|
||||
"CentralAltitude", "UtcOffset", "MagneticVariation", "ShorelineName"};
|
||||
Map<String, Object> outputMap = parseAtomicElements(docEle, regattaElements); // Regatta contains only atomic elements
|
||||
|
||||
//System.out.println(outputMap);
|
||||
//return outputMap;
|
||||
}
|
||||
|
||||
private static void parseRaceXML(Document doc) {
|
||||
// TODO: 27/04/17 ajm412 This is an extremely long method. Needs to be broken down.
|
||||
Element docEle = doc.getDocumentElement();
|
||||
String[] atomicRaceElements = {"RaceID", "RaceType", "CreationTimeDate"};
|
||||
Map<String, Object> outputMap = parseAtomicElements(docEle, atomicRaceElements);
|
||||
|
||||
//Race Start Time
|
||||
Map<String, Object> raceStartMap = new HashMap<>();
|
||||
Node raceStartTime = docEle.getElementsByTagName("RaceStartTime").item(0);
|
||||
raceStartMap.put("Start", getNodeNamedAttribute(raceStartTime, "Start"));
|
||||
raceStartMap.put("Postpone", getNodeNamedAttribute(raceStartTime, "Postpone"));
|
||||
outputMap.put("RaceStartTime", raceStartMap);
|
||||
|
||||
//Race Participants
|
||||
NodeList participants = docEle.getElementsByTagName("Participants").item(0).getChildNodes();
|
||||
outputMap.put("Participants", parseRaceParticipants(participants));
|
||||
|
||||
//Course (CompoundMarks)
|
||||
NodeList course = docEle.getElementsByTagName("Course").item(0).getChildNodes();
|
||||
outputMap.put("Course", parseCourse(course));
|
||||
|
||||
//CompoundMark Sequence
|
||||
NodeList markSequence = docEle.getElementsByTagName("CompoundMarkSequence").item(0).getChildNodes();
|
||||
outputMap.put("CourseMarkSequence", parseMarkSequence(markSequence));
|
||||
|
||||
//Course Limits
|
||||
NodeList courseLimits = docEle.getElementsByTagName("CourseLimit").item(0).getChildNodes();
|
||||
outputMap.put("CourseLimit", parseCourseLimits(courseLimits));
|
||||
|
||||
System.out.println(outputMap.get("Course"));
|
||||
// for (Map.Entry<String, Object> entry : outputMap.entrySet()) {
|
||||
// System.out.println(entry);
|
||||
// }
|
||||
}
|
||||
|
||||
private static ArrayList<Map> parseRaceParticipants(NodeList participants) {
|
||||
ArrayList<Map> participantList = new ArrayList<>();
|
||||
for (int i = 0; i < participants.getLength(); i++) {
|
||||
Map<String, Object> participantMap = new HashMap<>();
|
||||
Integer sourceID = null;
|
||||
String entry = null;
|
||||
Node participant = participants.item(i);
|
||||
if (participant.getNodeName().equals("Yacht")) {
|
||||
sourceID = Integer.parseInt(getNodeNamedAttribute(participant, "SourceID"));
|
||||
if (participant.getAttributes().getLength() == 2) {
|
||||
entry = getNodeNamedAttribute(participant, "Entry");
|
||||
}
|
||||
participantMap.put("sourceID", sourceID);
|
||||
participantMap.put("Entry", entry);
|
||||
participantList.add(participantMap);
|
||||
}
|
||||
}
|
||||
return participantList;
|
||||
}
|
||||
|
||||
private static Map<Integer, Object> parseCourse(NodeList course) {
|
||||
Map<Integer, Object> courseMap = new TreeMap<>();
|
||||
ArrayList<Map> courseList = new ArrayList<>();
|
||||
for (int i = 0; i < course.getLength(); i++) {
|
||||
|
||||
Integer compoundMarkID = null;
|
||||
String name = null;
|
||||
//map for an individual CompoundMark
|
||||
Map<Integer, Object> compoundMarkMap = new TreeMap<>();
|
||||
Node compoundMark = course.item(i);
|
||||
if (compoundMark.getNodeName().equals("CompoundMark")) {
|
||||
compoundMarkID = Integer.parseInt(getNodeNamedAttribute(compoundMark, "CompoundMarkID"));
|
||||
name = getNodeNamedAttribute(compoundMark, "Name");
|
||||
//get marks for compound mark
|
||||
NodeList marks = compoundMark.getChildNodes();
|
||||
for (int j = 0; j < marks.getLength(); j++) {
|
||||
//map for individual mark details within a compound mark
|
||||
Map<String, Object> markMap = new TreeMap<>();
|
||||
Node mark = marks.item(j);
|
||||
if (mark.getNodeName().equals("Mark")) {
|
||||
markMap.put("Name", getNodeNamedAttribute(mark, "Name"));
|
||||
markMap.put("TargetLat", Double.parseDouble(getNodeNamedAttribute(mark, "TargetLat")));
|
||||
markMap.put("TargetLng", Double.parseDouble(getNodeNamedAttribute(mark, "TargetLng")));
|
||||
markMap.put("SourceID", Integer.parseInt(getNodeNamedAttribute(mark, "SourceID")));
|
||||
compoundMarkMap.put(Integer.parseInt(getNodeNamedAttribute(mark, "SeqID")), markMap);
|
||||
}
|
||||
}
|
||||
courseMap.put(compoundMarkID, compoundMarkMap);
|
||||
}
|
||||
}
|
||||
|
||||
return courseMap;
|
||||
}
|
||||
|
||||
private static Map<Integer, Object> parseMarkSequence(NodeList markSequence) {
|
||||
Map<Integer, Object> markSequenceMap = new TreeMap<>();
|
||||
|
||||
for (int i = 0; i < markSequence.getLength(); i++) {
|
||||
Map<String, Object> cornerMap = new TreeMap<>();
|
||||
Node corner = markSequence.item(i);
|
||||
if (corner.getNodeName().equals("Corner")) {
|
||||
cornerMap.put("CompoundMarkID", Integer.parseInt(getNodeNamedAttribute(corner, "CompoundMarkID")));
|
||||
cornerMap.put("Rounding", getNodeNamedAttribute(corner, "Rounding"));
|
||||
cornerMap.put("ZoneSize", getNodeNamedAttribute(corner, "ZoneSize"));
|
||||
markSequenceMap.put(Integer.parseInt(getNodeNamedAttribute(corner, "SeqID")), cornerMap);
|
||||
}
|
||||
}
|
||||
|
||||
return markSequenceMap;
|
||||
}
|
||||
|
||||
private static Map<Integer, Object> parseCourseLimits(NodeList courseLimits) {
|
||||
Map<Integer, Object> courseLimitMap = new TreeMap<>();
|
||||
|
||||
for (int i = 0; i < courseLimits.getLength(); i++) {
|
||||
Map<String, Object> limitMap = new HashMap<>();
|
||||
Node limit = courseLimits.item(i);
|
||||
if (limit.getNodeName().equals("Limit")) {
|
||||
limitMap.put("Lat", Double.parseDouble(getNodeNamedAttribute(limit,"Lat")));
|
||||
limitMap.put("Lon", Double.parseDouble(getNodeNamedAttribute(limit,"Lon")));
|
||||
courseLimitMap.put(Integer.parseInt(getNodeNamedAttribute(limit, "SeqID")), limitMap);
|
||||
}
|
||||
}
|
||||
|
||||
return courseLimitMap;
|
||||
}
|
||||
|
||||
private static void parseBoatXML(Document doc) {
|
||||
// TODO: 27/04/17 ajm412
|
||||
}
|
||||
|
||||
private static String getNodeNamedAttribute(Node n, String attr) {
|
||||
return n.getAttributes().getNamedItem(attr).getTextContent();
|
||||
}
|
||||
|
||||
private static Map<String, Object> parseAtomicElements(Element docEle, String[] elements) {
|
||||
Map <String, Object> outputMap = new HashMap<>();
|
||||
for (String element : elements) {
|
||||
Object elementValue = null;
|
||||
if (docEle.getElementsByTagName(element).getLength() == 1) {
|
||||
String elementText = docEle.getElementsByTagName(element).item(0).getTextContent();
|
||||
// TODO: 27/04/17 ajm412: this seems messy, trying to parse values as ints/doubles to the map rather than as Strings. Possibly use RegEx.
|
||||
try {
|
||||
elementValue = Integer.parseInt(elementText);
|
||||
} catch (NumberFormatException nfe1) {
|
||||
try {
|
||||
elementValue = Double.parseDouble(elementText);
|
||||
} catch (NumberFormatException nfe2) {
|
||||
elementValue = elementText;
|
||||
}
|
||||
}
|
||||
}
|
||||
outputMap.put(element, elementValue);
|
||||
}
|
||||
|
||||
return outputMap;
|
||||
}
|
||||
|
||||
private static void extractRaceStartStatus(StreamPacket packet){
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
import com.sun.org.apache.xpath.internal.SourceTree;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class XMLParser {
|
||||
|
||||
RegattaXMLObject createRegattaXML(Document doc) {
|
||||
return new RegattaXMLObject(doc);
|
||||
}
|
||||
|
||||
RaceXMLObject createRaceXML(Document doc) {
|
||||
return new RaceXMLObject(doc);
|
||||
}
|
||||
|
||||
BoatXMLObject createBoatXML(Document doc) {
|
||||
return new BoatXMLObject(doc);
|
||||
}
|
||||
|
||||
// TODO: 29/04/17 ajm412: Data Validation here to return null if a tag somehow doesn't actually exist.
|
||||
private static Integer getElementInt(Element ele, String tag) {
|
||||
return Integer.parseInt(ele.getElementsByTagName(tag).item(0).getTextContent());
|
||||
}
|
||||
|
||||
private static String getElementString(Element ele, String tag) {
|
||||
return ele.getElementsByTagName(tag).item(0).getTextContent();
|
||||
}
|
||||
|
||||
private static Double getElementDouble(Element ele, String tag) {
|
||||
return Double.parseDouble(ele.getElementsByTagName(tag).item(0).getTextContent());
|
||||
}
|
||||
|
||||
private static String getNodeAttributeString(Node n, String attr) {
|
||||
return n.getAttributes().getNamedItem(attr).getTextContent();
|
||||
}
|
||||
|
||||
private static Integer getNodeAttributeInt(Node n, String attr) {
|
||||
return Integer.parseInt(n.getAttributes().getNamedItem(attr).getTextContent());
|
||||
}
|
||||
|
||||
private static Double getNodeAttributeDouble(Node n, String attr) {
|
||||
return Double.parseDouble(n.getAttributes().getNamedItem(attr).getTextContent());
|
||||
}
|
||||
|
||||
class RegattaXMLObject {
|
||||
|
||||
//Regatta Info
|
||||
private Integer regattaID;
|
||||
private String regattaName;
|
||||
private String courseName;
|
||||
private Double centralLat;
|
||||
private Double centralLng;
|
||||
private Integer utcOffset;
|
||||
|
||||
RegattaXMLObject(Document doc) {
|
||||
Element docEle = doc.getDocumentElement();
|
||||
|
||||
this.regattaID = getElementInt(docEle, "RegattaID");
|
||||
this.regattaName = getElementString(docEle, "RegattaName");
|
||||
this.courseName = getElementString(docEle, "CourseName");
|
||||
this.centralLat = getElementDouble(docEle, "CentralLatitude");
|
||||
this.centralLng = getElementDouble(docEle, "CentralLongitude");
|
||||
this.utcOffset = getElementInt(docEle, "UtcOffset");
|
||||
}
|
||||
|
||||
public Integer getRegattaID() { return regattaID; }
|
||||
public String getRegattaName() { return regattaName; }
|
||||
public String getCourseName() { return courseName; }
|
||||
public Double getCentralLat() { return centralLat; }
|
||||
public Double getCentralLng() { return centralLng; }
|
||||
public Integer getUtcOffset() { return utcOffset; }
|
||||
|
||||
}
|
||||
|
||||
class RaceXMLObject {
|
||||
|
||||
// Race Info
|
||||
Integer raceID;
|
||||
String raceType;
|
||||
String creationTimeDate; // XML Creation Time
|
||||
|
||||
//Race Start Details
|
||||
String raceStartTime;
|
||||
Boolean postponeStatus;
|
||||
|
||||
//Non atomic race attributes
|
||||
ArrayList<Participant> participants;
|
||||
ArrayList<CompoundMark> course;
|
||||
ArrayList<Corner> compoundMarkSequence;
|
||||
ArrayList<Limit> courseLimit;
|
||||
|
||||
RaceXMLObject(Document doc) {
|
||||
Element docEle = doc.getDocumentElement();
|
||||
participants = new ArrayList<>();
|
||||
|
||||
NodeList pList = docEle.getElementsByTagName("Participants").item(0).getChildNodes();
|
||||
for (int i = 0; i < pList.getLength(); i++) {
|
||||
Node pNode = pList.item(i);
|
||||
String entry;
|
||||
if (pNode.getNodeName().equals("Yacht")) {
|
||||
Integer sourceID = getNodeAttributeInt(pNode, "SourceID");
|
||||
|
||||
if (pNode.getAttributes().getLength() == 2) {
|
||||
entry = getNodeAttributeString(pNode, "Entry");
|
||||
} else {
|
||||
entry = null;
|
||||
}
|
||||
|
||||
Participant pa = new Participant(sourceID, entry);
|
||||
participants.add(pa);
|
||||
}
|
||||
}
|
||||
|
||||
course = new ArrayList<>();
|
||||
|
||||
NodeList cMarkList = docEle.getElementsByTagName("Course").item(0).getChildNodes();
|
||||
for (int i = 0; i < cMarkList.getLength(); i++) {
|
||||
Node cMarkNode = cMarkList.item(i);
|
||||
if (cMarkNode.getNodeName().equals("CompoundMark")) {
|
||||
CompoundMark cMark = new CompoundMark(cMarkNode);
|
||||
course.add(cMark);
|
||||
}
|
||||
}
|
||||
|
||||
compoundMarkSequence = new ArrayList<>();
|
||||
|
||||
NodeList cornerList = docEle.getElementsByTagName("CompoundMarkSequence").item(0).getChildNodes();
|
||||
for (int i = 0; i < cornerList.getLength(); i++) {
|
||||
Node cornerNode = cornerList.item(i);
|
||||
if (cornerNode.getNodeName().equals("Corner")) {
|
||||
Corner corner = new Corner(cornerNode);
|
||||
compoundMarkSequence.add(corner);
|
||||
}
|
||||
}
|
||||
|
||||
courseLimit = new ArrayList<>();
|
||||
|
||||
NodeList limitList = docEle.getElementsByTagName("CourseLimit").item(0).getChildNodes();
|
||||
for (int i = 0; i < limitList.getLength(); i++) {
|
||||
Node limitNode = limitList.item(i);
|
||||
if (limitNode.getNodeName().equals("Limit")) {
|
||||
Limit limit = new Limit(limitNode);
|
||||
courseLimit.add(limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Participant> getParticipants() { return participants; }
|
||||
public ArrayList<CompoundMark> getCompoundMarks() { return course; }
|
||||
public ArrayList<Corner> getCompoundMarkSequence() { return compoundMarkSequence; }
|
||||
public ArrayList<Limit> getCourseLimit() { return courseLimit; }
|
||||
|
||||
class Participant {
|
||||
Integer sourceID;
|
||||
String entry;
|
||||
|
||||
Participant(Integer sourceID, String entry) {
|
||||
this.sourceID = sourceID;
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
public Integer getsourceID() { return sourceID; }
|
||||
public String getEntry() { return entry; }
|
||||
}
|
||||
|
||||
class CompoundMark {
|
||||
private Integer markID;
|
||||
private String cMarkName;
|
||||
private ArrayList<Mark> marks;
|
||||
|
||||
CompoundMark(Node compoundMark) {
|
||||
marks = new ArrayList<>();
|
||||
this.markID = getNodeAttributeInt(compoundMark, "CompoundMarkID");
|
||||
this.cMarkName = getNodeAttributeString(compoundMark, "Name");
|
||||
NodeList childMarks = compoundMark.getChildNodes();
|
||||
for (int i = 0; i < childMarks.getLength(); i++) {
|
||||
Node markNode = childMarks.item(i);
|
||||
if (markNode.getNodeName().equals("Mark")) {
|
||||
Mark mark = new Mark(markNode);
|
||||
marks.add(mark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getMarkID() { return markID; }
|
||||
public String getcMarkName() { return cMarkName; }
|
||||
public ArrayList<Mark> getMarks() { return marks; }
|
||||
|
||||
class Mark {
|
||||
private Integer seqID;
|
||||
private Integer sourceID;
|
||||
private String markName;
|
||||
private Double targetLat;
|
||||
private Double targetLng;
|
||||
|
||||
Mark(Node markNode) {
|
||||
|
||||
this.seqID = getNodeAttributeInt(markNode, "SeqID");
|
||||
this.sourceID = getNodeAttributeInt(markNode, "SourceID");
|
||||
this.markName = getNodeAttributeString(markNode, "Name");
|
||||
this.targetLat = getNodeAttributeDouble(markNode, "TargetLat");
|
||||
this.targetLng = getNodeAttributeDouble(markNode, "TargetLng");
|
||||
|
||||
}
|
||||
|
||||
public Integer getSeqID() { return seqID; }
|
||||
public Integer getSourceID() { return sourceID; }
|
||||
public String getMarkName() { return markName; }
|
||||
public Double getTargetLat() { return targetLat; }
|
||||
public Double getTargetLng() { return targetLng; }
|
||||
}
|
||||
}
|
||||
|
||||
class Corner {
|
||||
private Integer seqID;
|
||||
private Integer compoundMarkID;
|
||||
private String rounding;
|
||||
private Integer zoneSize;
|
||||
|
||||
Corner(Node cornerNode) {
|
||||
this.seqID = getNodeAttributeInt(cornerNode, "SeqID");
|
||||
this.compoundMarkID = getNodeAttributeInt(cornerNode, "CompoundMarkID");
|
||||
this.rounding = getNodeAttributeString(cornerNode, "Rounding");
|
||||
this.zoneSize = getNodeAttributeInt(cornerNode, "ZoneSize");
|
||||
|
||||
}
|
||||
|
||||
public Integer getSeqID() { return seqID; }
|
||||
public Integer getCompoundMarkID() { return compoundMarkID; }
|
||||
public String getRounding() { return rounding; }
|
||||
public Integer getZoneSize() { return zoneSize; }
|
||||
}
|
||||
|
||||
class Limit {
|
||||
private Integer seqID;
|
||||
private Double lat;
|
||||
private Double lng;
|
||||
|
||||
Limit(Node limitNode) {
|
||||
this.seqID = getNodeAttributeInt(limitNode, "SeqID");
|
||||
this.lat = getNodeAttributeDouble(limitNode, "Lat");
|
||||
this.lng = getNodeAttributeDouble(limitNode, "Lon");
|
||||
}
|
||||
|
||||
public Integer getSeqID() { return seqID; }
|
||||
public Double getLat() { return lat; }
|
||||
public Double getLng() { return lng; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BoatXMLObject {
|
||||
|
||||
private String lastModified;
|
||||
private Integer version;
|
||||
|
||||
//Settings for the boat type in the race. This may end up having to be reworked if multiple boat types compete.
|
||||
private String boatType;
|
||||
private Double boatLength;
|
||||
private Double hullLength;
|
||||
private Double markZoneSize;
|
||||
private Double courseZoneSize;
|
||||
private ArrayList<Double> zoneLimits;// will only contain 5 elements. Limits 1-5
|
||||
|
||||
//Boats
|
||||
ArrayList<Boat> boats;
|
||||
|
||||
BoatXMLObject(Document doc) {
|
||||
|
||||
Element docEle = doc.getDocumentElement();
|
||||
|
||||
this.lastModified = getElementString(docEle, "Modified");
|
||||
this.version = getElementInt(docEle, "Version");
|
||||
|
||||
NodeList settingsList = docEle.getElementsByTagName("Settings").item(0).getChildNodes();
|
||||
this.boatType = getNodeAttributeString(settingsList.item(1), "Type");
|
||||
this.boatLength = getNodeAttributeDouble(settingsList.item(3), "BoatLength");
|
||||
this.hullLength = getNodeAttributeDouble(settingsList.item(3), "HullLength");
|
||||
this.markZoneSize = getNodeAttributeDouble(settingsList.item(5), "MarkZoneSize");
|
||||
this.courseZoneSize = getNodeAttributeDouble(settingsList.item(5), "CourseZoneSize");
|
||||
|
||||
Node zoneLimitsList = settingsList.item(7);
|
||||
this.zoneLimits = new ArrayList<>();
|
||||
for (int i = 0; i < zoneLimitsList.getAttributes().getLength(); i++) {
|
||||
String tag = String.format("Limit%d", i+1);
|
||||
this.zoneLimits.add(getNodeAttributeDouble(zoneLimitsList, tag));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getLastModified() { return lastModified; }
|
||||
public Integer getVersion() { return version; }
|
||||
public String getBoatType() { return boatType; }
|
||||
public Double getBoatLength() { return boatLength; }
|
||||
public Double getHullLength() { return hullLength; }
|
||||
public Double getMarkZoneSize() { return markZoneSize; }
|
||||
public Double getCourseZoneSize() { return courseZoneSize; }
|
||||
public ArrayList<Double> getZoneLimits() { return zoneLimits; }
|
||||
public ArrayList<Boat> getBoats() { return boats; }
|
||||
|
||||
class Boat {
|
||||
|
||||
private String boatType;
|
||||
private Integer sourceID;
|
||||
private String hullID; //matches HullNum in the XML spec.
|
||||
private String shortName;
|
||||
private String boatName;
|
||||
private String country;
|
||||
private String skipper;
|
||||
|
||||
Boat(Node boatNode) {
|
||||
// TODO: 29/04/17 Actually build the boats.
|
||||
}
|
||||
|
||||
public String getBoatType() { return boatType; }
|
||||
public Integer getSourceID() { return sourceID; }
|
||||
public String getHullID() { return hullID; }
|
||||
public String getShortName() { return shortName; }
|
||||
public String getBoatName() { return boatName; }
|
||||
public String getCountry() { return country; }
|
||||
public String getSkipper() { return skipper; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user