From 45053ba507bdae9deb2e55529e404b8d76cea2e0 Mon Sep 17 00:00:00 2001 From: Michael Rausch Date: Wed, 19 Jul 2017 14:47:16 +1200 Subject: [PATCH] Added XML Generation - Implemented a wrapper for Apache Freemake - Implemented the regatta XML generator Tags: #story[984] --- pom.xml | 7 ++ .../seng302/gameServer/GameServerThread.java | 2 +- .../java/seng302/gameServer/GameState.java | 3 - .../MainServerThread.java | 15 +++ src/main/java/seng302/models/xml/Boats.java | 22 +++++ src/main/java/seng302/models/xml/Race.java | 5 + src/main/java/seng302/models/xml/Regatta.java | 74 +++++++++++++++ .../java/seng302/models/xml/XMLGenerator.java | 92 +++++++++++++++++++ .../server_config/xml_templates/boats.ftlh | 36 ++++++++ .../server_config/xml_templates/regatta.ftlh | 11 +++ 10 files changed, 263 insertions(+), 4 deletions(-) create mode 100644 src/main/java/seng302/models/xml/Boats.java create mode 100644 src/main/java/seng302/models/xml/Race.java create mode 100644 src/main/java/seng302/models/xml/Regatta.java create mode 100644 src/main/java/seng302/models/xml/XMLGenerator.java create mode 100644 src/main/resources/server_config/xml_templates/boats.ftlh create mode 100644 src/main/resources/server_config/xml_templates/regatta.ftlh diff --git a/pom.xml b/pom.xml index 8d10c6fc..296a4f01 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,13 @@ 2.7.13 test + + + + org.freemarker + freemarker + 2.3.26-incubating + diff --git a/src/main/java/seng302/gameServer/GameServerThread.java b/src/main/java/seng302/gameServer/GameServerThread.java index 9f127773..342b6e65 100644 --- a/src/main/java/seng302/gameServer/GameServerThread.java +++ b/src/main/java/seng302/gameServer/GameServerThread.java @@ -40,7 +40,7 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel runner.start(); } - static void serverLog(String message, int logLevel){ + public static void serverLog(String message, int logLevel){ if(logLevel <= LOG_LEVEL){ System.out.println("[SERVER] " + message); } diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index d36968fc..9dcaed8a 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -59,7 +59,4 @@ public class GameState { } } - - - } diff --git a/src/main/java/seng302/gameServerWithThreading/MainServerThread.java b/src/main/java/seng302/gameServerWithThreading/MainServerThread.java index 226e1dc8..c0168aa6 100644 --- a/src/main/java/seng302/gameServerWithThreading/MainServerThread.java +++ b/src/main/java/seng302/gameServerWithThreading/MainServerThread.java @@ -2,9 +2,13 @@ package seng302.gameServerWithThreading; import seng302.gameServer.GameStages; import seng302.gameServer.GameState; +import seng302.models.mark.Mark; +import seng302.models.mark.MarkType; import seng302.models.stream.PacketBufferDelegate; import seng302.models.stream.StreamParser; import seng302.models.stream.packets.StreamPacket; +import seng302.models.xml.Regatta; +import seng302.models.xml.XMLGenerator; import java.io.IOException; import java.net.ServerSocket; @@ -40,6 +44,17 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{ public void run() { + // @TODO remove before commit + XMLGenerator g = new XMLGenerator(); + + Regatta r = new Regatta("Test regatta", 1.123, 4.456); + r.setMagneticVariation(12.1); + r.setUtcOffset(12); + + g.setRegatta(r); + + System.out.println("g.getRegattaAsXml() = " + g.getRegattaAsXml()); + //You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app. while (!isInterrupted()) { try { diff --git a/src/main/java/seng302/models/xml/Boats.java b/src/main/java/seng302/models/xml/Boats.java new file mode 100644 index 00000000..1257e5be --- /dev/null +++ b/src/main/java/seng302/models/xml/Boats.java @@ -0,0 +1,22 @@ +package seng302.models.xml; + +import seng302.models.mark.Mark; + +import java.util.ArrayList; +import java.util.List; + +public class Boats { + private List marks; + + public Boats(){ + marks = new ArrayList<>(); + } + + public void addMark(Mark m){ + marks.add(m); + } + + public List getMarks(){ + return this.marks; + } +} diff --git a/src/main/java/seng302/models/xml/Race.java b/src/main/java/seng302/models/xml/Race.java new file mode 100644 index 00000000..a0e8dc32 --- /dev/null +++ b/src/main/java/seng302/models/xml/Race.java @@ -0,0 +1,5 @@ +package seng302.models.xml; + +public class Race { + +} diff --git a/src/main/java/seng302/models/xml/Regatta.java b/src/main/java/seng302/models/xml/Regatta.java new file mode 100644 index 00000000..7c9dd448 --- /dev/null +++ b/src/main/java/seng302/models/xml/Regatta.java @@ -0,0 +1,74 @@ +package seng302.models.xml; + +public class Regatta { + private final Double DEFAULT_ALTITUDE = 0d; + private final Integer DEFAULT_REGATTA_ID = 0; + + private Integer id; + private String name; + private String courseName; + + private Double latitude; + private Double longitude; + private Double altitude; + + private Integer utcOffset; + private Double magneticVariation; + + public Regatta(String name, Double latitude, Double longitude) { + this.name = name; + this.id = DEFAULT_REGATTA_ID; + this.courseName = name; + + this.latitude = latitude; + this.longitude = longitude; + this.altitude = DEFAULT_ALTITUDE; + + this.utcOffset = 0; + this.magneticVariation = 0d; + } + + public void setMagneticVariation(Double magneticVariation){ + this.magneticVariation = magneticVariation; + } + + public void setUtcOffset(Integer offset){ + this.utcOffset = offset; + } + + /* + NOTE!! The following getters must follow the JavaBean standard (getPropertyName()), and must be public. + */ + + public String getName(){ + return name; + } + + public String getCourseName(){ + return courseName; + } + + public Integer getRegattaId(){ + return id; + } + + public Double getLatitude() { + return latitude; + } + + public Double getLongitude() { + return longitude; + } + + public Double getAltitude() { + return altitude; + } + + public Integer getUtcOffset(){ + return utcOffset; + } + + public Double getMagneticVariation(){ + return magneticVariation; + } +} diff --git a/src/main/java/seng302/models/xml/XMLGenerator.java b/src/main/java/seng302/models/xml/XMLGenerator.java new file mode 100644 index 00000000..09ee9924 --- /dev/null +++ b/src/main/java/seng302/models/xml/XMLGenerator.java @@ -0,0 +1,92 @@ +package seng302.models.xml; + +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; +import seng302.server.messages.XMLMessageSubType; + +import java.io.*; +import java.net.URISyntaxException; + +public class XMLGenerator { + private static final String XML_TEMPLATE_DIR = "/server_config/xml_templates"; + private static final String REGATTA_TEMPLATE_NAME = "regatta.ftlh"; + private Configuration configuration; + private Regatta regatta; + + /** + * Set up a configuration instance for Apache Freemake + */ + private void setupConfiguration() { + configuration = new Configuration(Configuration.VERSION_2_3_26); + + try { + configuration.setDirectoryForTemplateLoading(new File(getClass().getResource(XML_TEMPLATE_DIR).toURI())); + } catch (IOException e){ + System.out.println("[FATAL] Server could not read XML templates"); + } catch (URISyntaxException e) { + System.out.println("[FATAL] Xml template directory URI is invalid"); + } catch (NullPointerException e){ + System.out.println("[FATAL] Server could not load XML Template directory, ensure this directory isn't empty"); + } + } + + public XMLGenerator(){ + setupConfiguration(); + } + + public void setRegatta(Regatta regatta){ + this.regatta = regatta; + } + + private String parseToXmlString(String templateName, XMLMessageSubType type) throws IOException, TemplateException { + Template template; + ByteArrayOutputStream os = new ByteArrayOutputStream(); + OutputStreamWriter writer = new OutputStreamWriter(os); + + template = configuration.getTemplate(templateName); + + switch (type) { + case REGATTA: + template.process(regatta, writer); + break; + + case BOAT: + template.process(regatta, writer); + break; + + case RACE: + template.process(regatta, writer); + break; + + default: + throw new UnsupportedOperationException(); + } + + try { + return os.toString("UTF-8"); + } catch (UnsupportedEncodingException e) { + System.out.println("[FATAL] UTF-8 Not supported"); + return null; + } + } + + public String getRegattaAsXml(){ + String result = null; + + if (regatta == null) return null; + + try { + result = parseToXmlString(REGATTA_TEMPLATE_NAME, XMLMessageSubType.REGATTA); + } catch (TemplateException e) { + System.out.println("[FATAL] Error parsing regatta"); + } catch (IOException e) { + System.out.println("[FATAL] Error reading regatta"); + } + + return result; + } + + + +} \ No newline at end of file diff --git a/src/main/resources/server_config/xml_templates/boats.ftlh b/src/main/resources/server_config/xml_templates/boats.ftlh new file mode 100644 index 00000000..b2d6f3bb --- /dev/null +++ b/src/main/resources/server_config/xml_templates/boats.ftlh @@ -0,0 +1,36 @@ + + + + 2012-05-17T07:49:40+0200 + 12 + + + + + + + + + + <#-- Not used --> + + + + <#list marks as mark> + + + + + + + <#list boats as boat> + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/server_config/xml_templates/regatta.ftlh b/src/main/resources/server_config/xml_templates/regatta.ftlh new file mode 100644 index 00000000..25543c15 --- /dev/null +++ b/src/main/resources/server_config/xml_templates/regatta.ftlh @@ -0,0 +1,11 @@ + + + ${regattaId} + ${name} + ${courseName} + ${latitude} + ${longitude} + ${altitude} + ${utcOffset} + ${magneticVariation} + \ No newline at end of file