org.goobi.production.model.bibliography.course.CourseToGerman.java Source code

Java tutorial

Introduction

Here is the source code for org.goobi.production.model.bibliography.course.CourseToGerman.java

Source

/*
 * (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 &lt;matthias.ronge@zeutschel.de&gt;
 */
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;
    }
}