/* * ----------------------------------------------------------------------- * Copyright © 2013-2016 Meno Hochschild, <http://www.menodata.de/> * ----------------------------------------------------------------------- * This file (WeekdataProviderSPI.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.i18n; import net.time4j.Weekday; import net.time4j.base.ResourceLoader; import net.time4j.format.WeekdataProvider; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Set; /** * <p>Standard-SPI-Implementierung eines {@code WeekdataProvider}. </p> * * @author Meno Hochschild * @since 2.2 */ public class WeekdataProviderSPI implements WeekdataProvider { //~ Instanzvariablen -------------------------------------------------- private final String source; private final Set<String> countriesWithMinDays4; private final Map<String, Weekday> firstDayOfWeek; private final Map<String, Weekday> startOfWeekend; private final Map<String, Weekday> endOfWeekend; //~ Konstruktoren ----------------------------------------------------- public WeekdataProviderSPI() { super(); String name = "data/week.data"; URI uri = ResourceLoader.getInstance().locate("i18n", WeekdataProviderSPI.class, name); InputStream is = ResourceLoader.getInstance().load(uri, true); if (is == null) { try { is = ResourceLoader.getInstance().load(WeekdataProviderSPI.class, name, true); } catch (IOException ioe) { // we print a warning on System.err (see below) } } if (is != null) { this.source = "@" + uri; Set<String> tmpMinDays4 = new HashSet<>(); Map<String, Weekday> tmpFirst = new HashMap<>(); Map<String, Weekday> tmpStart = new HashMap<>(); Map<String, Weekday> tmpEnd = new HashMap<>(); try { BufferedReader br = new BufferedReader( new InputStreamReader(is, "US-ASCII")); String line; while ((line = br.readLine()) != null) { if (line.startsWith("#")) { continue; // Kommentarzeile überspringen } int equal = line.indexOf('='); String prefix = line.substring(0, equal).trim(); String[] list = line.substring(equal + 1).split(" "); if (prefix.equals("minDays-4")) { for (String country : list) { String key = country.trim().toUpperCase(Locale.US); if (!key.isEmpty()) { tmpMinDays4.add(key); } } continue; } String wd; Weekday weekday; Map<String, Weekday> map; if (prefix.startsWith("start-")) { wd = prefix.substring(6); weekday = Weekday.SATURDAY; map = tmpStart; } else if (prefix.startsWith("end-")) { wd = prefix.substring(4); weekday = Weekday.SUNDAY; map = tmpEnd; } else if (prefix.startsWith("first-")) { wd = prefix.substring(6); weekday = Weekday.MONDAY; map = tmpFirst; } else { throw new IllegalStateException( "Unexpected format: " + this.source); } switch (wd) { case "sun": weekday = Weekday.SUNDAY; break; case "sat": weekday = Weekday.SATURDAY; break; case "fri": weekday = Weekday.FRIDAY; break; case "thu": weekday = Weekday.THURSDAY; break; case "wed": weekday = Weekday.WEDNESDAY; break; case "tue": weekday = Weekday.TUESDAY; break; case "mon": weekday = Weekday.MONDAY; break; } for (String country : list) { String key = country.trim().toUpperCase(Locale.US); if (!key.isEmpty()) { map.put(key, weekday); } } } this.countriesWithMinDays4 = Collections.unmodifiableSet(tmpMinDays4); this.firstDayOfWeek = Collections.unmodifiableMap(tmpFirst); this.startOfWeekend = Collections.unmodifiableMap(tmpStart); this.endOfWeekend = Collections.unmodifiableMap(tmpEnd); } catch (UnsupportedEncodingException uee) { throw new AssertionError(uee); } catch (Exception ex) { throw new IllegalStateException( "Unexpected format: " + this.source, ex); } finally { try { is.close(); } catch (IOException ioe) { ioe.printStackTrace(System.err); } } } else { this.source = "@STATIC"; this.countriesWithMinDays4 = Collections.emptySet(); this.firstDayOfWeek = Collections.emptyMap(); this.startOfWeekend = Collections.emptyMap(); this.endOfWeekend = Collections.emptyMap(); System.err.println("Warning: File \"" + name + "\" not found."); } } //~ Methoden ---------------------------------------------------------- @Override public int getFirstDayOfWeek(Locale country) { if (this.firstDayOfWeek.isEmpty()) { // fallback GregorianCalendar gc = new GregorianCalendar(country); int fd = gc.getFirstDayOfWeek(); return ((fd == 1) ? 7 : (fd - 1)); } String key = country.getCountry(); Weekday first = Weekday.MONDAY; if (this.firstDayOfWeek.containsKey(key)) { first = this.firstDayOfWeek.get(key); } return first.getValue(); } @Override public int getMinimalDaysInFirstWeek(Locale country) { if (this.countriesWithMinDays4.isEmpty()) { // fallback GregorianCalendar gc = new GregorianCalendar(country); return gc.getMinimalDaysInFirstWeek(); } String key = country.getCountry(); int minDays = 1; if (key.isEmpty() && country.getLanguage().isEmpty()) { minDays = 4; // ISO-8601 } else if (this.countriesWithMinDays4.contains(key)) { minDays = 4; } return minDays; } @Override public int getStartOfWeekend(Locale country) { String key = country.getCountry(); Weekday start = Weekday.SATURDAY; if (this.startOfWeekend.containsKey(key)) { start = this.startOfWeekend.get(key); } return start.getValue(); } @Override public int getEndOfWeekend(Locale country) { String key = country.getCountry(); Weekday end = Weekday.SUNDAY; if (this.endOfWeekend.containsKey(key)) { end = this.endOfWeekend.get(key); } return end.getValue(); } @Override public String toString() { return this.getClass().getName() + this.source; } }