net.time4j.engine.CalendarFamily Maven / Gradle / Ivy
/*
* -----------------------------------------------------------------------
* Copyright © 2013-2015 Meno Hochschild,
* -----------------------------------------------------------------------
* 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 .
* -----------------------------------------------------------------------
*/
package net.time4j.engine;
import java.util.List;
import java.util.Map;
/**
* Represents a set of various calendar systems as members of a family.
*
* @param generic type compatible to {@link CalendarVariant}
* @author Meno Hochschild
* @since 3.4/4.3
*/
/*[deutsch]
* Repräsentiert eine Familie von miteinander verwandten Kalendersystemen.
*
* @param generic type compatible to {@link CalendarVariant}
* @author Meno Hochschild
* @since 3.4/4.3
*/
public final class CalendarFamily>
extends Chronology {
//~ Instanzvariablen --------------------------------------------------
private final Map> calendars; // must never be exposed
//~ Konstruktoren -----------------------------------------------------
private CalendarFamily(
Class chronoType,
ChronoMerger chronoMerger,
Map, ElementRule> ruleMap,
List extensions,
Map> calendars
) {
super(chronoType, chronoMerger, ruleMap, extensions);
this.calendars = calendars;
}
//~ Methoden ----------------------------------------------------------
@Override
public boolean hasCalendarSystem() {
return true;
}
@Override
public CalendarSystem 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 getCalendarSystem(String variant) {
CalendarSystem 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 ----------------------------------------------------
/**
* Creates a builder for a new calendar family
* and will only be used during loading a class of a calendar variant
* in a static initializer.
*
* Instances of this class will be created by the static factory method {@code setUp()}.
*
* @param generic type of time context
* @author Meno Hochschild
* @see #setUp(Class,ChronoMerger,Map)
* @since 3.4/4.3
* @doctags.concurrency {mutable}
*/
/*[deutsch]
* Erzeugt einen Builder für eine neue Kalenderfamilie und wird ausschließlich beim Laden einer
* Klasse zu einer Kalendervariante in einem static initializer benutzt.
*
* Instanzen dieser Klasse werden über die statische {@code setUp()}-Fabrikmethode erzeugt.
*
* @param 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>
extends Chronology.Builder {
//~ Instanzvariablen ----------------------------------------------
private final Map> calendars;
//~ Konstruktoren -------------------------------------------------
private Builder(
Class chronoType,
ChronoMerger merger,
Map> calendars
) {
super(chronoType, merger);
if (calendars.isEmpty()) {
throw new IllegalArgumentException("Missing calendar variants.");
}
this.calendars = calendars;
}
//~ Methoden ------------------------------------------------------
/**
* Creates a builder for building a calendar family.
*
* @param 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]
* Erzeugt ein Hilfsobjekt zum Bauen einer Kalenderfamilie.
*
* @param 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 > Builder setUp(
Class chronoType,
ChronoMerger merger,
Map> calendars
) {
return new Builder<>(chronoType, merger, calendars);
}
@Override
public Builder appendElement(
ChronoElement element,
ElementRule rule
) {
super.appendElement(element, rule);
return this;
}
@Override
public Builder appendExtension(ChronoExtension extension) {
super.appendExtension(extension);
return this;
}
/**
* Creates and registers a calendar family.
*
* @return new chronology as calendar family
* @throws IllegalStateException if already registered or in case of inconsistencies
* @since 3.4/4.3
*/
/*[deutsch]
* Erzeugt und registriert eine Kalenderfamilie.
*
* @return new chronology as calendar family
* @throws IllegalStateException if already registered or in case of inconsistencies
* @since 3.4/4.3
*/
@Override
public CalendarFamily build() {
CalendarFamily engine =
new CalendarFamily<>(
this.chronoType,
this.merger,
this.ruleMap,
this.extensions,
this.calendars
);
Chronology.register(engine);
return engine;
}
}
}