/* * ----------------------------------------------------------------------- * Copyright © 2013-2016 Meno Hochschild, <http://www.menodata.de/> * ----------------------------------------------------------------------- * This file (CalendarFamily.java) is part of project Time4J. * * Time4J is free software: You can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * Time4J is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Time4J. If not, see <http://www.gnu.org/licenses/>. * ----------------------------------------------------------------------- */ package net.time4j.engine; import java.util.List; import java.util.Map; /** * <p>Represents a set of various calendar systems as members of a family. </p> * * @param <T> generic type compatible to {@link CalendarVariant} * @author Meno Hochschild * @since 3.4/4.3 */ /*[deutsch] * <p>Repräsentiert eine Familie von miteinander verwandten Kalendersystemen. </p> * * @param <T> generic type compatible to {@link CalendarVariant} * @author Meno Hochschild * @since 3.4/4.3 */ public final class CalendarFamily<T extends CalendarVariant<T>> extends Chronology<T> { //~ Instanzvariablen -------------------------------------------------- private final Map<String, ? extends CalendarSystem<T>> calendars; // must never be exposed //~ Konstruktoren ----------------------------------------------------- private CalendarFamily( Class<T> chronoType, ChronoMerger<T> chronoMerger, Map<ChronoElement<?>, ElementRule<T, ?>> ruleMap, List<ChronoExtension> extensions, Map<String, ? extends CalendarSystem<T>> calendars ) { super(chronoType, chronoMerger, ruleMap, extensions); this.calendars = calendars; } //~ Methoden ---------------------------------------------------------- @Override public boolean hasCalendarSystem() { return true; } @Override public CalendarSystem<T> getCalendarSystem() { if (this.calendars.size() == 1) { return this.calendars.values().iterator().next(); } else { throw new ChronoException("Cannot determine calendar system without variant."); } } @Override public CalendarSystem<T> getCalendarSystem(String variant) { if (variant.isEmpty()) { return this.getCalendarSystem(); } CalendarSystem<T> result = this.calendars.get(variant); if (result == null) { return super.getCalendarSystem(variant); } else { return result; } } @Override public boolean isSupported(ChronoElement<?> element) { return super.isSupported(element) || (element instanceof EpochDays); } //~ Innere Klassen ---------------------------------------------------- /** * <p>Creates a builder for a new calendar family * and will only be used during loading a class of a calendar variant * in a <i>static initializer</i>. </p> * * <p>Instances of this class will be created by the static factory method {@code setUp()}. </p> * * @param <T> generic type of time context * @author Meno Hochschild * @see #setUp(Class,ChronoMerger,Map) * @since 3.4/4.3 * @doctags.concurrency {mutable} */ /*[deutsch] * <p>Erzeugt einen Builder für eine neue Kalenderfamilie und wird ausschließlich beim Laden einer * Klasse zu einer Kalendervariante in einem <i>static initializer</i> benutzt. </p> * * <p>Instanzen dieser Klasse werden über die statische {@code setUp()}-Fabrikmethode erzeugt. </p> * * @param <T> generic type of time context * @author Meno Hochschild * @see #setUp(Class,ChronoMerger,Map) * @since 3.4/4.3 * @doctags.concurrency {mutable} */ public static final class Builder<T extends CalendarVariant<T>> extends Chronology.Builder<T> { //~ Instanzvariablen ---------------------------------------------- private final Map<String, ? extends CalendarSystem<T>> calendars; //~ Konstruktoren ------------------------------------------------- private Builder( Class<T> chronoType, ChronoMerger<T> merger, Map<String, ? extends CalendarSystem<T>> calendars ) { super(chronoType, merger); if (calendars.isEmpty()) { throw new IllegalArgumentException("Missing calendar variants."); } this.calendars = calendars; } //~ Methoden ------------------------------------------------------ /** * <p>Creates a builder for building a calendar family. </p> * * @param <T> generic type of time context * @param chronoType reified chronological type * @param merger generic replacement for static creation of variant objects * @param calendars map of variant names to calendar systems * @return new {@code Builder} object * @throws IllegalArgumentException if no calendar system is specified * @since 3.4/4.3 */ /*[deutsch] * <p>Erzeugt ein Hilfsobjekt zum Bauen einer Kalenderfamilie. </p> * * @param <T> generic type of time context * @param chronoType reified chronological type * @param merger generic replacement for static creation of variant objects * @param calendars map of variant names to calendar systems * @return new {@code Builder} object * @throws IllegalArgumentException if no calendar system is specified * @since 3.4/4.3 */ public static <T extends CalendarVariant<T>> Builder<T> setUp( Class<T> chronoType, ChronoMerger<T> merger, Map<String, ? extends CalendarSystem<T>> calendars ) { return new Builder<>(chronoType, merger, calendars); } @Override public <V> Builder<T> appendElement( ChronoElement<V> element, ElementRule<T, V> rule ) { super.appendElement(element, rule); return this; } @Override public Builder<T> appendExtension(ChronoExtension extension) { super.appendExtension(extension); return this; } /** * <p>Creates and registers a calendar family. </p> * * @return new chronology as calendar family * @throws IllegalStateException if already registered or in case of inconsistencies * @since 3.4/4.3 */ /*[deutsch] * <p>Erzeugt und registriert eine Kalenderfamilie. </p> * * @return new chronology as calendar family * @throws IllegalStateException if already registered or in case of inconsistencies * @since 3.4/4.3 */ @Override public CalendarFamily<T> build() { CalendarFamily<T> engine = new CalendarFamily<>( this.chronoType, this.merger, this.ruleMap, this.extensions, this.calendars ); Chronology.register(engine); return engine; } } }