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 = 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", // 2 digits, left pad 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. */ @Override 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 */ @Override public int compareTo(IMember member) { return Long.compare(this.key, member.getKey()); } @Override public String getName() { return this.name; } @Override public Gender getGender() { return this.gender; } @Override public LocalDate getDate() { return this.date; } @Override public String getFirstName() { return this.firstname; } @Override public long getKey() { return this.key; } @Override public KindOfSport getKindOfSport() { return this.kindOfSport; } }