summaryrefslogtreecommitdiff
path: root/AlgoAufgabe1/src/de/ostfalia/algo/ws18/s1/Member.java
blob: 0d0c9bd90afde539aa9e756b5ec090f8ef5a2bba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package de.ostfalia.algo.ws18.s1;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

import de.ostfalia.algo.ws18.base.Gender;
import de.ostfalia.algo.ws18.base.IMember;
import de.ostfalia.algo.ws18.base.KindOfSport;

public class Member implements IMember {
	/**
	 * Schlüssel kodiert als:
	 *   Anfangsbuchstabe des Namens, codiert in
	 *     zwei Dezimalziffern a -> 01, b -> 02, …, z -> 26.
	 *     Diese Zuordnung gilt für Groß- und Kleinbuchstaben,
	 *     Umlaute werden als ae, oe, ue dargestellt.
	 *   Anfangsbuchstabe des Vornamens, codiert in
	 *     zwei Dezimalziffern, siehe Name
	 *   Geburtsdatum, ttmmjjjj
	 *
	 *   Sie können davon ausgehen, dass doppelte Schlüssel nicht vorkommen.
	 */
	private long key;

	/**
	 * Name.
	 */
	private String name;
	
	/**
	 * Firstname.
	 */
	private String firstname;

	/**
	 * Date.
	 */
	private LocalDate date;

	/**
	 * Gender.
	 */
	private Gender gender;
	
	/**
	 * Associated kind of sport.
	 */
	private KindOfSport kindOfSport;
	
	/**
	 * Parse a CSV to a Member.
	 * 
	 * @param csv A CSV String separated by ', ',
	 * with the row signature 'name, firstname, date, gender, kind of sport'
	 * @return A Member.
	 */
	public Member(String csv) {
		final String DELIMITER = ", ";
		String[] columns = csv.split(DELIMITER);
		
		if (columns.length != 5) {
			throw new IllegalArgumentException(
					"Row '" + csv + "' is not a valid format!");
		}

		this.name = columns[0];
		this.firstname = columns[1];
		this.date = LocalDate.parse(columns[2],
				DateTimeFormatter.ISO_DATE);
		this.gender = Gender.valueOf(columns[3]);
		this.kindOfSport = KindOfSport.valueOf(columns[4]);
		this.key = encode(this);
	}

	/**
	 * Member constructor.
	 * 
	 * @param name The name.
	 * @param firstname The firstname.
	 * @param date The date.
	 * @param gender The gender.
	 * @param kindOfSport The associated kind of sport.
	 */
	public Member(String name,
			String firstname,
			LocalDate date,
			Gender gender,
			KindOfSport kindOfSport) {
		this.name = name;
		this.firstname = firstname;
		this.date = date;
		this.gender = gender;
		this.kindOfSport = kindOfSport;
		this.key = encode(this);
	}
	
	/**
	 * Generate a unique key from a member's attributes. 
	 * 
	 * @param member A member.
	 * @return A key.
	 */
	private static Long encode(Member member) {
		String nameKeyPart = encodeLetters(member.name.substring(0, 1));
		String surnameKeyPart = encodeLetters(member.firstname.substring(0, 1));
		String dateKeyPart = encodeDate(member.date);
		String key = String.format("%s%s%s",
				nameKeyPart,
				surnameKeyPart,
				dateKeyPart);
		return Long.valueOf(key);
	}

	/**
	 * Format the given date as part of a key.
	 * 
	 * @param date A LocalDate.
	 * @return A String ttmmjjjj.
	 */
	private static String encodeDate(LocalDate date) {
		return String.format("%02d%02d%02d",
				date.getDayOfMonth(),
				date.getMonthValue(),
				date.getYear());
	}

	/**
	 * Map each letter in the given string to a value
	 * between '01' and '26'.
	 * 
	 * @param string A string containing only letters.
	 * @return A string of zero padded digits.
	 */
	private static String encodeLetters(String string) {
		String encodedString = "";

		for (char letter : sanitizeLetters(string).toCharArray()) {
			int letterIndex = letter - 'a' + 1;

			if (letterIndex < 1 || letterIndex > 26) {
				throw new IllegalArgumentException(
						letter + " cannot be encoded!");
			}

			encodedString += String.format("%02d", letterIndex);
		}

		return encodedString;
	}

	/**
	 * Replace ä, ö, ü and lowercase the string.
	 * 
	 * @param string A string.
	 * @return A lowercase string without umlauts.
	 */
	private static String sanitizeLetters(String string) {
		return string
				.toLowerCase()
				.replace("ä", "ae")
				.replace("ö", "oe")
				.replace("ü", "ue");
	}

	/**
	 * Return this member as string.
	 */
	public String toString() {
		return this.key + ", "
				+ this.name + ", "
				+ this.firstname + ", "
				+ this.date + ", "
				+ this.gender + ", "
				+ this.kindOfSport;
	}
	
	/**
	 * Implement the Comparable interface by comparing the keys.
	 * 
	 * @return @see Comparable
	 */
	public int compareTo(IMember member) {
		return Long.compare(this.key, member.getKey());
	}
	
	public String getName() {
		return this.name;
	}
	
	public Gender getGender() {
		return this.gender;
	}
	
	public LocalDate getDate() {
		return this.date;
	}
	
	public String getFirstName() {
		return this.firstname;
	}
	
	public long getKey() {
		return this.key;
	}
	
	public KindOfSport getKindOfSport() {
		return this.kindOfSport;
	}
}