diff --git a/.classpath b/.classpath
index e536da1..60117f5 100644
--- a/.classpath
+++ b/.classpath
@@ -1,39 +1,45 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 036e5df..8f37ff9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,6 +118,11 @@
h2
test
+
+ commons-io
+ commons-io
+ 2.6
+
diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionDetails.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionDetails.java
new file mode 100644
index 0000000..a37d2bd
--- /dev/null
+++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionDetails.java
@@ -0,0 +1,24 @@
+package de.kreth.vaadin.clubhelper.vaadinclubhelper.data;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CompetitionDetails implements Serializable {
+
+ private static final long serialVersionUID = 2167132205051467946L;
+
+ private Set cpGroups;
+
+ public Set getCpGroups() {
+ return cpGroups;
+ }
+
+ public void parseCompetitionGroups(String text) {
+ cpGroups = new HashSet<>();
+ String[] lines = text.split("\n");
+ for (String line: lines) {
+ cpGroups.add(CompetitionGroup.parseLine(line));
+ }
+ }
+}
diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroup.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroup.java
new file mode 100644
index 0000000..9cc8b16
--- /dev/null
+++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroup.java
@@ -0,0 +1,70 @@
+package de.kreth.vaadin.clubhelper.vaadinclubhelper.data;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.google.common.io.Files;
+
+public class CompetitionGroup implements Serializable {
+
+ private static final long serialVersionUID = 8670759590642549124L;
+ public static final int OPEN_END_MAX_YEAR = 9999;
+ public static final int OPEN_END_MIN_YEAR = 0;
+
+ private static final Pattern YEAR_PATTERN = Pattern.compile("[^a-zA-Z](\\d{2,4})");
+ private static final Rules RULES = new Rules();
+ private int minBirthYear;
+ private int maxBirthYear = OPEN_END_MAX_YEAR;
+
+ public int getOldestBirthYear() {
+ return minBirthYear;
+ }
+
+ public int getYoungestBirthYear() {
+ return maxBirthYear;
+ }
+
+ public static CompetitionGroup parseLine(String line) {
+ CompetitionGroup competitionGroup = new CompetitionGroup();
+
+ Matcher matcher = YEAR_PATTERN.matcher(line);
+ if (matcher.find()) {
+ competitionGroup.minBirthYear = Integer.parseInt(matcher.group(1));
+ }
+ if (matcher.find()) {
+ competitionGroup.maxBirthYear = Integer.parseInt(matcher.group(1));
+ } else {
+ if (RULES.isYoungestOnly(line)) {
+ competitionGroup.maxBirthYear = competitionGroup.minBirthYear;
+ competitionGroup.minBirthYear = OPEN_END_MIN_YEAR;
+ }
+ }
+
+ return competitionGroup;
+ }
+
+ private static class Rules {
+ final String youngest;
+
+ public Rules() {
+ URL uri = getClass().getResource("CompetitionGroupRules.txt");
+ try {
+ List lines = Files.readLines(new File(uri.toURI()), Charset.defaultCharset());
+ youngest = lines.get(0);
+ } catch (IOException | URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public boolean isYoungestOnly(String line) {
+ return line.toLowerCase().contains(youngest);
+ }
+ }
+}
diff --git a/src/main/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupRules.txt b/src/main/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupRules.txt
new file mode 100644
index 0000000..b84186d
--- /dev/null
+++ b/src/main/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupRules.txt
@@ -0,0 +1 @@
+älter
\ No newline at end of file
diff --git a/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/AbstractCompetitionDataTests.java b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/AbstractCompetitionDataTests.java
new file mode 100644
index 0000000..a4219ea
--- /dev/null
+++ b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/AbstractCompetitionDataTests.java
@@ -0,0 +1,27 @@
+package de.kreth.vaadin.clubhelper.vaadinclubhelper.data;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+import org.apache.commons.io.FileUtils;
+
+public class AbstractCompetitionDataTests {
+
+ public AbstractCompetitionDataTests() {
+ super();
+ }
+
+ public String getGroupTable1() throws IOException, URISyntaxException {
+ URL uri = getClass().getResource("CompetitionGroupsBezirksEinzelMS2018.txt");
+ return FileUtils.readFileToString(new File(uri.toURI()), Charset.defaultCharset());
+ }
+
+ public String getGroupTable2() throws IOException, URISyntaxException {
+ URL uri = getClass().getResource("CompetitionGroupsLM2018Trampolin.txt");
+ return FileUtils.readFileToString(new File(uri.toURI()), Charset.defaultCharset());
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionDetailsTest.java b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionDetailsTest.java
new file mode 100644
index 0000000..5695d14
--- /dev/null
+++ b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionDetailsTest.java
@@ -0,0 +1,22 @@
+package de.kreth.vaadin.clubhelper.vaadinclubhelper.data;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class CompetitionDetailsTest extends AbstractCompetitionDataTests {
+
+ @Test
+ public void parseGroupInsertsElementPerLine() throws Exception {
+
+ CompetitionDetails detail = new CompetitionDetails();
+ detail.parseCompetitionGroups(getGroupTable1());
+ assertEquals(8, detail.getCpGroups().size());
+
+ detail = new CompetitionDetails();
+ detail.parseCompetitionGroups(getGroupTable2());
+ assertEquals(6, detail.getCpGroups().size());
+
+
+ }
+}
diff --git a/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupLineParseTest.java b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupLineParseTest.java
new file mode 100644
index 0000000..5522c1d
--- /dev/null
+++ b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupLineParseTest.java
@@ -0,0 +1,65 @@
+package de.kreth.vaadin.clubhelper.vaadinclubhelper.data;
+
+import static org.junit.Assert.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+
+public class CompetitionGroupLineParseTest {
+
+ @Test
+ public void testTwo4DigitYears() {
+
+ CompetitionGroup group = CompetitionGroup.parseLine("Schüler – innen E 2008 -2009 P4");
+ assertEquals(2009, group.getYoungestBirthYear());
+
+ group = CompetitionGroup.parseLine("Heranwachsende 2001-1995 P8");
+ assertEquals(1995, group.getYoungestBirthYear());
+
+ group = CompetitionGroup.parseLine("Jugend C: Jg. 2004/2005 W11 - W13");
+ assertEquals(2005, group.getYoungestBirthYear());
+
+ group = CompetitionGroup.parseLine("Schüler – innen E 2008 -2009 P4");
+ assertEquals(2008, group.getOldestBirthYear());
+
+ group = CompetitionGroup.parseLine("Jugend E: 2008 und jünger P8 - W11");
+ assertEquals(2008, group.getOldestBirthYear());
+
+ group = CompetitionGroup.parseLine("Heranwachsende 2001-1995 P8");
+ assertEquals(2001, group.getOldestBirthYear());
+
+ group = CompetitionGroup.parseLine("Jugend C: Jg. 2004/2005 W11 - W13");
+ assertEquals(2004, group.getOldestBirthYear());
+
+ }
+
+ @Test
+ public void testOneYearIsYoungest() {
+
+ CompetitionGroup group = CompetitionGroup.parseLine("Erwachsene: Jg. 1996 und älter W15 - FIG A");
+ assertEquals(1996, group.getYoungestBirthYear());
+ }
+
+ @Test
+ public void testOneYearIsOldest() {
+ CompetitionGroup group = CompetitionGroup.parseLine("Schüler – innen F 2010 und jünger P3");
+ assertEquals(2010, group.getOldestBirthYear());
+
+ group = CompetitionGroup.parseLine("Jugend E: 2008 und jünger P8 - W11");
+ assertEquals(2008, group.getOldestBirthYear());
+
+ }
+
+ @Test
+ public void testRegexPattern() {
+ Pattern pattern = Pattern.compile("\\d{2,4}");
+ String twoYears = "text 1999 bis 2009 text";
+ Matcher matcher = pattern.matcher(twoYears);
+ assertTrue("didnt find first year", matcher.find());
+ assertEquals("1999", matcher.group());
+ assertTrue("didnt find second year", matcher.find());
+ assertEquals("2009", matcher.group());
+ }
+}
diff --git a/src/test/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupsBezirksEinzelMS2018.txt b/src/test/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupsBezirksEinzelMS2018.txt
new file mode 100644
index 0000000..2c9db55
--- /dev/null
+++ b/src/test/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupsBezirksEinzelMS2018.txt
@@ -0,0 +1,8 @@
+Schüler – innen F 2010 und jünger P3
+Schüler – innen E 2008 -2009 P4
+Schüler – innen D 2006 - 2007 P5
+Schüler – innen C 2004 - 2005 P6
+Schüler – innen B 2002 - 2003 P7
+Heranwachsende 2001-1995 P8
+Turner - innen 1996 -1989 P8
+Oldies 1988 und älter P5
\ No newline at end of file
diff --git a/src/test/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupsLM2018Trampolin.txt b/src/test/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupsLM2018Trampolin.txt
new file mode 100644
index 0000000..81e7097
--- /dev/null
+++ b/src/test/resources/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/CompetitionGroupsLM2018Trampolin.txt
@@ -0,0 +1,6 @@
+Jugend E: 2008 und jünger P8 - W11
+Jugend D: Jg. 2006/2007 W9 (alte M5) - W11
+Jugend C: Jg. 2004/2005 W11 - W13
+Jugend B: Jg. 2002/2003 W13 - W15
+Jugend A: Jg. 1997-2001 W15 - FIG A
+Erwachsene: Jg. 1996 und älter W15 - FIG A
\ No newline at end of file