Java tutorial
/* * (c) Kitodo. Key to digital objects e. V. <contact@kitodo.org> * * This file is part of the Kitodo project. * * It is licensed under GNU General Public License version 3 or later. * * For the full copyright and license information, please read the * GPL3-License.txt file that was distributed with this source code. */ package org.goobi.production.model.bibliography.course; import de.sub.goobi.helper.DateUtils; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import java.util.TreeSet; import org.joda.time.DateTimeConstants; import org.joda.time.LocalDate; /** * The static class CourseToGerman provides a toString() method to convert a * course of appearance into a verbal description in German language. * * @author Matthias Ronge <matthias.ronge@zeutschel.de> */ public class CourseToGerman { /** * Days of weeks names in German. * * <p> * Joda times days of week are 1-based, where 1 references Monday through 7 * references Sunday. Therefore the null? in first place. * </p> */ private static final String[] DAYS_OF_WEEK_NAMES = new String[] { null, "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" }; /** * Months names in German. * * <p> * Joda times months are 1-based, therefore the null? in first place. * </p> */ private static final String[] MONTH_NAMES = new String[] { null, "Januar", "Februar", "Mrz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" }; /** * The function toString() returns a verbal description of the course of * appearance in German. * * @return Verbal description of the course in German */ public static List<String> asReadableText(Course course) { List<String> result = new ArrayList<>(); if (course.isEmpty()) { return result; } Iterator<Block> blocks = course.iterator(); boolean hasPreviousBlock = false; do { Block block = blocks.next(); result.add(titleToString(block, hasPreviousBlock)); for (Issue issue : block.getIssues()) { String irregularities = irregularitiesToString(issue); if (irregularities != null) { result.add(irregularities); } } hasPreviousBlock = true; } while (blocks.hasNext()); return result; } /** * The function titleToString() formulates the regular appearance of a block * in German language. * * @param block * Titel to formulate * @param subsequentBlock * false for the first block, true otherwise */ private static String titleToString(Block block, boolean subsequentBlock) { StringBuilder result = new StringBuilder(500); int currentIssuesSize = block.getIssues().size(); if (!subsequentBlock) { result.append("Die Zeitung erschien vom "); appendDate(result, block.getFirstAppearance()); } else { result.append("Ab dem "); appendDate(result, block.getFirstAppearance()); result.append(" erschien die Zeitung unter dem gleichen Titel"); } result.append(" bis zum "); appendDate(result, block.getLastAppearance()); result.append(" regelmig "); Iterator<Issue> issueIterator = block.getIssues().iterator(); for (int issueIndex = 0; issueIndex < currentIssuesSize; issueIndex++) { Issue issue = issueIterator.next(); result.append("an allen "); int daysOfWeekCount = 0; for (int dayOfWeek = DateTimeConstants.MONDAY; dayOfWeek <= DateTimeConstants.SUNDAY; dayOfWeek++) { if (issue.isDayOfWeek(dayOfWeek)) { result.append(DAYS_OF_WEEK_NAMES[dayOfWeek]); result.append("en"); daysOfWeekCount++; if (daysOfWeekCount < issue.getDaysOfWeek().size() - 1) { result.append(", "); } if (daysOfWeekCount == issue.getDaysOfWeek().size() - 1) { result.append(" und "); } } } result.append(" als "); result.append(issue.getHeading()); if (issueIndex < currentIssuesSize - 2) { result.append(", "); } if (issueIndex == currentIssuesSize - 2) { result.append(" sowie "); } if (issueIndex == currentIssuesSize - 1) { result.append("."); } } return result.toString(); } /** * The function irregularitiesToString() formulates the irregularities of a * given issue in German language. * * @param issue * issues whose irregularities shall be formulated */ private static String irregularitiesToString(Issue issue) { int additionsSize = issue.getAdditions().size(); int exclusionsSize = issue.getExclusions().size(); StringBuilder buffer = new StringBuilder( (int) (Math.ceil(10.907 * (additionsSize + exclusionsSize)) + 500)); if (additionsSize == 0 && exclusionsSize == 0) { return null; } buffer.append("Die Ausgabe "); buffer.append(issue.getHeading()); buffer.append(" erschien "); if (exclusionsSize > 0) { appendManyDates(buffer, issue.getExclusions(), false); if (additionsSize > 0) { buffer.append(", dafr jedoch "); } } if (additionsSize > 0) { appendManyDates(buffer, issue.getAdditions(), true); } buffer.append("."); return buffer.toString(); } /** * The method appendManyDates() converts a lot of date objects into readable * text in German language. * * @param buffer * StringBuilder to write to * @param dates * Set of dates to convert to text * @param signum * sign, i.e. true for additions, false for exclusions * @throws NoSuchElementException * if dates has no elements * @throws NullPointerException * if buffer or dates is null */ private static void appendManyDates(StringBuilder buffer, Set<LocalDate> dates, boolean signum) { if (signum) { buffer.append("zustzlich "); } else { buffer.append("nicht "); } TreeSet<LocalDate> orderedDates = dates instanceof TreeSet ? (TreeSet<LocalDate>) dates : new TreeSet<>(dates); Iterator<LocalDate> datesIterator = orderedDates.iterator(); LocalDate current = datesIterator.next(); LocalDate next = datesIterator.hasNext() ? datesIterator.next() : null; LocalDate overNext = datesIterator.hasNext() ? datesIterator.next() : null; int previousYear = Integer.MIN_VALUE; boolean nextInSameMonth = false; boolean nextBothInSameMonth = next != null && DateUtils.sameMonth(current, next); int lastMonthOfYear = DateUtils.lastMonthForYear(orderedDates, current.getYear()); do { nextInSameMonth = nextBothInSameMonth; nextBothInSameMonth = DateUtils.sameMonth(next, overNext); if (previousYear != current.getYear()) { buffer.append("am "); } buffer.append(current.getDayOfMonth()); buffer.append('.'); if (!nextInSameMonth) { buffer.append(' '); buffer.append(MONTH_NAMES[current.getMonthOfYear()]); } if (!DateUtils.sameYear(current, next)) { buffer.append(' '); buffer.append(current.getYear()); if (next != null) { if (!DateUtils.sameYear(next, orderedDates.last())) { buffer.append(", "); } else { buffer.append(" und ebenfalls "); if (!signum) { buffer.append("nicht "); } } } if (next != null) { lastMonthOfYear = DateUtils.lastMonthForYear(orderedDates, next.getYear()); } } else if (next != null) { if (nextInSameMonth && nextBothInSameMonth || !nextInSameMonth && next.getMonthOfYear() != lastMonthOfYear) { buffer.append(", "); } else { buffer.append(" und "); } } previousYear = current.getYear(); current = next; next = overNext; overNext = datesIterator.hasNext() ? datesIterator.next() : null; } while (current != null); } /** * The method appendDate() writes a date to the buffer. * * @param buffer * Buffer to write to * @param date * Date to write */ private static void appendDate(StringBuilder buffer, LocalDate date) { buffer.append(date.getDayOfMonth()); buffer.append(". "); buffer.append(MONTH_NAMES[date.getMonthOfYear()]); buffer.append(' '); buffer.append(date.getYear()); return; } }