diff --git a/src/main/java/de/jollyday/AbstractI18nObject.java b/src/main/java/de/jollyday/AbstractI18nObject.java
new file mode 100644
index 00000000..82a4aee1
--- /dev/null
+++ b/src/main/java/de/jollyday/AbstractI18nObject.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright 2019 Sven Diedrichsen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package de.jollyday;
+
+import java.util.Locale;
+
+import de.jollyday.util.ResourceUtil;
+
+/**
+ * Represents a localizable object.
+ *
+ * @author Christoph Weitkamp
+ * @version $Id: $
+ */
+public abstract class AbstractI18nObject {
+ /**
+ * The calculated hashcode cached for performance.
+ */
+ protected int hashCode = 0;
+ /**
+ * The properties key to retrieve the description with.
+ */
+ protected final String propertiesKey;
+
+ /**
+ * Utility for accessing resources.
+ */
+ protected final ResourceUtil resourceUtil = new ResourceUtil();
+
+ /**
+ * Constructs a country using the provided ISO code to retrieve the
+ * description with.
+ *
+ * @param propertiesKey
+ * a {@link java.lang.String} object.
+ */
+ public AbstractI18nObject(String propertiesKey) {
+ super();
+ this.propertiesKey = propertiesKey;
+ }
+
+ /**
+ *
+ * Getter for the propertiesKey.
+ *
+ *
+ * @return the country properties key
+ */
+ public String getPropertiesKey() {
+ return propertiesKey;
+ }
+
+ /**
+ * The description read with the default locale.
+ *
+ * @return Description for this object
+ */
+ public String getDescription() {
+ return getDescription(Locale.getDefault());
+ }
+
+ /**
+ * The description read with the provided locale.
+ *
+ * @param locale
+ * a {@link java.util.Locale} object.
+ * @return Description for this object
+ */
+ public String getDescription(Locale locale) {
+ return resourceUtil.getCountryDescription(locale, propertiesKey);
+ }
+
+ @Override
+ public String toString() {
+ return propertiesKey + " (" + getDescription() + ")";
+ }
+
+ @Override
+ public abstract int hashCode();
+}
diff --git a/src/main/java/de/jollyday/City.java b/src/main/java/de/jollyday/City.java
new file mode 100644
index 00000000..1cde11d1
--- /dev/null
+++ b/src/main/java/de/jollyday/City.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright 2019 Sven Diedrichsen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package de.jollyday;
+
+/**
+ * Represents a city and contains the city code and a localized description.
+ *
+ * @author Christoph Weitkamp
+ * @version $Id: $
+ */
+public final class City extends AbstractI18nObject implements Comparable {
+ /**
+ * The ISO code to retrieve the description with.
+ */
+ private final String isoCode;
+ /**
+ * The region code to retrieve the description with.
+ */
+ private final String regionCode;
+ /**
+ * The city code to retrieve the description with.
+ */
+ private final String code;
+
+ /**
+ * Constructs a city using the provided code to retrieve the description
+ * with.
+ *
+ * @param isoCode
+ * a {@link java.lang.String} object.
+ * @param regionCode
+ * a {@link java.lang.String} object.
+ * @param code
+ * a {@link java.lang.String} object.
+ */
+ public City(String isoCode, String regionCode, String code) {
+ super(isoCode + "." + regionCode + "." + code);
+ this.isoCode = isoCode;
+ this.regionCode = regionCode;
+ this.code = code;
+ }
+
+ /**
+ *
+ * Getter for the field isoCode.
+ *
+ *
+ * @return the ISO code
+ */
+ public String getISOCode() {
+ return isoCode;
+ }
+
+ /**
+ *
+ * Getter for the field regionCode.
+ *
+ *
+ * @return the region code
+ */
+ public String getRegionCode() {
+ return regionCode;
+ }
+
+ /**
+ *
+ * Getter for the field code.
+ *
+ *
+ * @return the city code
+ */
+ public String getCode() {
+ return code;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof City) {
+ City other = (City) obj;
+ return isoCode.equals(other.isoCode) && regionCode.equals(other.regionCode) && code.equals(other.code);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ if (hashCode == 0) {
+ int hash = 1;
+ hash = hash * 31 + isoCode.hashCode();
+ hash = hash * 31 + regionCode.hashCode();
+ hash = hash * 31 + code.hashCode();
+ hashCode = hash;
+ }
+ return hashCode;
+ }
+
+ /**
+ * Compares this city to another city.
+ *
+ * The comparison is primarily based on the city code.
+ *
+ * @param other
+ * the other city to compare to, not null
+ * @return the comparator value, negative if less, positive if greater
+ */
+ @Override
+ public int compareTo(City other) {
+ return code.compareTo(other.code);
+ }
+}
diff --git a/src/main/java/de/jollyday/Country.java b/src/main/java/de/jollyday/Country.java
new file mode 100644
index 00000000..5764d0b3
--- /dev/null
+++ b/src/main/java/de/jollyday/Country.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright 2019 Sven Diedrichsen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package de.jollyday;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a country. It contains the ISO code, a localized description and a
+ * list of regions.
+ *
+ * @author Christoph Weitkamp
+ * @version $Id: $
+ */
+public final class Country extends AbstractI18nObject implements Comparable {
+ /**
+ * The ISO code to retrieve the description with.
+ */
+ private final String isoCode;
+ /**
+ * A map of regions inside this country
+ */
+ private final Map regions = new HashMap<>(0);
+
+ /**
+ * Constructs a country using the provided ISO code to retrieve the
+ * description with.
+ *
+ * @param isoCode
+ * a {@link java.lang.String} object.
+ */
+ public Country(String isoCode) {
+ super(isoCode);
+ this.isoCode = isoCode;
+ }
+
+ /**
+ *
+ * Getter for the field isoCode.
+ *
+ *
+ * @return the ISO code
+ */
+ public String getISOCode() {
+ return isoCode;
+ }
+
+ /**
+ * Adds a {@link Region} to this country.
+ *
+ * @param region
+ * a {@link Region} object.
+ */
+ public void addRegion(Region region) {
+ regions.put(region.getCode(), region);
+ }
+
+ /**
+ * The {@link Region}s of this country.
+ *
+ * @return an unmodifiable list of all {@link Region}s of this country
+ */
+ public Collection getRegions() {
+ return Collections.unmodifiableCollection(regions.values());
+ }
+
+ /**
+ * Returns a specific {@link Region}s of this country.
+ *
+ * @param regionCode
+ * {@link java.lang.String}the region code.
+ * @return a {@link Region} (could be null)
+ */
+ public Region getRegion(String regionCode) {
+ return regions.get(regionCode);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof Country) {
+ Country other = (Country) obj;
+ return isoCode.equals(other.isoCode) && regions.equals(other.regions);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ if (hashCode == 0) {
+ int hash = 1;
+ hash = hash * 31 + isoCode.hashCode();
+ hashCode = hash;
+ }
+ return hashCode;
+ }
+
+ /**
+ * Compares this country to another country.
+ *
+ * The comparison is primarily based on the ISO code.
+ *
+ * @param other
+ * the other country to compare to, not null
+ * @return the comparator value, negative if less, positive if greater
+ */
+ @Override
+ public int compareTo(Country other) {
+ return isoCode.compareTo(other.isoCode);
+ }
+}
diff --git a/src/main/java/de/jollyday/Holiday.java b/src/main/java/de/jollyday/Holiday.java
index 047355c2..1e51b424 100644
--- a/src/main/java/de/jollyday/Holiday.java
+++ b/src/main/java/de/jollyday/Holiday.java
@@ -15,40 +15,25 @@
*/
package de.jollyday;
-import de.jollyday.util.ResourceUtil;
-
import java.time.LocalDate;
import java.util.Locale;
/**
- * Represents the holiday and contains the actual date and an localized
+ * Represents the holiday and contains the actual date and a localized
* description.
*
* @author Sven Diedrichsen
* @version $Id: $
*/
-public final class Holiday implements Comparable {
- /**
- * The calculated hashcode cached for performance.
- */
- private int hashCode = 0;
+public final class Holiday extends AbstractI18nObject implements Comparable {
/**
* The date the holiday occurs.
*/
private final LocalDate date;
- /**
- * The properties key to retrieve the description with.
- */
- private final String propertiesKey;
-
/**
* The type of holiday. e.g. official holiday or not.
- * */
- private final HolidayType type;
- /**
- * Utility for accessing resources.
*/
- private final ResourceUtil resourceUtil = new ResourceUtil();
+ private final HolidayType type;
/**
* Constructs a holiday for a date using the provided properties key to
@@ -62,10 +47,9 @@ public final class Holiday implements Comparable {
* a {@link de.jollyday.HolidayType} object.
*/
public Holiday(LocalDate date, String propertiesKey, HolidayType type) {
- super();
- this.type = type;
+ super(propertiesKey == null ? "" : propertiesKey);
this.date = date;
- this.propertiesKey = propertiesKey == null ? "" : propertiesKey;
+ this.type = type;
}
/**
@@ -79,37 +63,6 @@ public LocalDate getDate() {
return date;
}
- /**
- *
- * Getter for the field propertiesKey.
- *
- *
- * @return the holidays properties key
- */
- public String getPropertiesKey() {
- return propertiesKey;
- }
-
- /**
- * The description read with the default locale.
- *
- * @return Description for this holiday
- */
- public String getDescription() {
- return resourceUtil.getHolidayDescription(Locale.getDefault(), getPropertiesKey());
- }
-
- /**
- * The description read with the provided locale.
- *
- * @param locale
- * a {@link java.util.Locale} object.
- * @return Description for this holiday
- */
- public String getDescription(Locale locale) {
- return resourceUtil.getHolidayDescription(locale, getPropertiesKey());
- }
-
@Override
public boolean equals(Object obj) {
if (obj == this) {
@@ -117,12 +70,16 @@ public boolean equals(Object obj) {
}
if (obj instanceof Holiday) {
Holiday other = (Holiday) obj;
- return other.date.equals(this.date) && other.propertiesKey.equals(this.propertiesKey)
- && type.equals(other.type);
+ return date.equals(other.date) && propertiesKey.equals(other.propertiesKey) && type.equals(other.type);
}
return false;
}
+ @Override
+ public String getDescription(Locale locale) {
+ return resourceUtil.getHolidayDescription(locale, propertiesKey);
+ }
+
@Override
public int hashCode() {
if (hashCode == 0) {
@@ -152,13 +109,15 @@ public HolidayType getType() {
/**
* Compares this holiday to another holiday.
*
- * The comparison is primarily based on the date, from earliest to latest by using the LocalDate comparator.
+ * The comparison is primarily based on the date, from earliest to latest by
+ * using the LocalDate comparator.
*
- * @param other the other holiday to compare to, not null
+ * @param other
+ * the other holiday to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
@Override
public int compareTo(Holiday other) {
- return this.getDate().compareTo(other.getDate());
+ return date.compareTo(other.date);
}
}
diff --git a/src/main/java/de/jollyday/Region.java b/src/main/java/de/jollyday/Region.java
new file mode 100644
index 00000000..71305e75
--- /dev/null
+++ b/src/main/java/de/jollyday/Region.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright 2019 Sven Diedrichsen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package de.jollyday;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a region. It contains the region code, a localized description and
+ * a list of cities.
+ *
+ * @author Christoph Weitkamp
+ * @version $Id: $
+ */
+public final class Region extends AbstractI18nObject implements Comparable {
+ /**
+ * The ISO code to retrieve the description with.
+ */
+ private final String isoCode;
+ /**
+ * The code to retrieve the description with.
+ */
+ private final String code;
+ /**
+ * A map of cities inside this region
+ */
+ private final Map cities = new HashMap<>(0);
+
+ /**
+ * Constructs a region using the provided code to retrieve the description
+ * with.
+ *
+ * @param isoCode
+ * a {@link java.lang.String} object.
+ * @param code
+ * a {@link java.lang.String} object.
+ */
+ public Region(String isoCode, String code) {
+ super(isoCode + "." + code);
+ this.isoCode = isoCode;
+ this.code = code;
+ }
+
+ /**
+ *
+ * Getter for the field isoCode.
+ *
+ *
+ * @return the ISO code
+ */
+ public String getISOCode() {
+ return isoCode;
+ }
+
+ /**
+ *
+ * Getter for the field code.
+ *
+ *
+ * @return the region code
+ */
+ public String getCode() {
+ return code;
+ }
+
+ /**
+ * Adds a {@link City} to this region.
+ *
+ * @param city
+ * a {@link City} object.
+ */
+ public void addCity(City city) {
+ cities.put(city.getCode(), city);
+ }
+
+ /**
+ * The {@link City Cities} of this region.
+ *
+ * @return an unmodifiable list of all {@link City Cities} of this region
+ */
+ public Collection getCities() {
+ return Collections.unmodifiableCollection(cities.values());
+ }
+
+ /**
+ * Returns a specific {@link City} of this region.
+ *
+ * @param cityCode
+ * {@link java.lang.String} the city code.
+ * @return a {@link City} (could be null)
+ */
+ public City getCity(String cityCode) {
+ return cities.get(cityCode);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof Region) {
+ Region other = (Region) obj;
+ return isoCode.equals(other.isoCode) && code.equals(other.code) && cities.equals(other.cities);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ if (hashCode == 0) {
+ int hash = 1;
+ hash = hash * 31 + isoCode.hashCode();
+ hash = hash * 31 + code.hashCode();
+ hashCode = hash;
+ }
+ return hashCode;
+ }
+
+ /**
+ * Compares this region to another region.
+ *
+ * The comparison is primarily based on the region code.
+ *
+ * @param other
+ * the other region to compare to, not null
+ * @return the comparator value, negative if less, positive if greater
+ */
+ @Override
+ public int compareTo(Region other) {
+ return code.compareTo(other.code);
+ }
+}
diff --git a/src/main/java/de/jollyday/configuration/CountryDescriptionProvider.java b/src/main/java/de/jollyday/configuration/CountryDescriptionProvider.java
new file mode 100644
index 00000000..5c7fe74a
--- /dev/null
+++ b/src/main/java/de/jollyday/configuration/CountryDescriptionProvider.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2019 Sven Diedrichsen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package de.jollyday.configuration;
+
+import java.util.Collection;
+
+import de.jollyday.City;
+import de.jollyday.Country;
+import de.jollyday.Region;
+
+/**
+ * The interface for Jollyday country description provider.
+ *
+ * @author Christoph Weitkamp
+ * @version $Id: $
+ */
+public interface CountryDescriptionProvider {
+
+ /**
+ * Returns a list of all {@link Country Countries}.
+ *
+ * @return an unmodifiable list of all {@link Country Countries}
+ */
+ Collection getCountries();
+
+ /**
+ * Returns a list of all {@link Region}s inside a given {@link Country}.
+ * Could be empty.
+ *
+ * @param isoCode
+ * {@link java.lang.String} sthe country code to retrieve the
+ * regions from.
+ * @return an unmodifiable list of all {@link Region}s inside the given
+ * {@link Country}
+ * @throws IllegalArgumentException
+ */
+ Collection getRegions(String isoCode);
+
+ /**
+ * Returns a list of all {@link City Cities} from a given {@link Region}.
+ * Could be empty.
+ *
+ * @param regionCode
+ * {@link java.lang.String} the region code to retrieve the
+ * cities from.
+ * @return an unmodifiable list of all {@link City Cities} inside the given
+ * {@link Region}
+ * @throws IllegalArgumentException
+ */
+ Collection getCities(String regionCode);
+}
diff --git a/src/main/java/de/jollyday/configuration/impl/CountryDescriptionProviderImpl.java b/src/main/java/de/jollyday/configuration/impl/CountryDescriptionProviderImpl.java
new file mode 100644
index 00000000..13c69e1d
--- /dev/null
+++ b/src/main/java/de/jollyday/configuration/impl/CountryDescriptionProviderImpl.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright 2019 Sven Diedrichsen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package de.jollyday.configuration.impl;
+
+import static de.jollyday.util.ResourceUtil.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import de.jollyday.City;
+import de.jollyday.Country;
+import de.jollyday.Region;
+import de.jollyday.configuration.CountryDescriptionProvider;
+import de.jollyday.util.ResourceUtil;
+
+/**
+ * An implementation of the Jollyday country description provider.
+ *
+ * @author Christoph Weitkamp
+ * @version $Id: $
+ */
+public class CountryDescriptionProviderImpl implements CountryDescriptionProvider {
+ /**
+ * Internal map of ISO code / country
+ */
+ final Map countries = new HashMap<>();
+ /**
+ * Internal map of ISO code / list of regions
+ */
+ final Map> regions = new HashMap<>();
+ /**
+ * Internal map of region code / list of cities
+ */
+ final Map> cities = new HashMap<>();
+
+ private final ResourceUtil resourceUtil = new ResourceUtil();
+
+ public CountryDescriptionProviderImpl() {
+ parseCountryDescriptions();
+ }
+
+ @Override
+ public Collection getCountries() {
+ return Collections.unmodifiableCollection(countries.values());
+ }
+
+ @Override
+ public Collection getRegions(String isoCode) {
+ if (regions.containsKey(isoCode)) {
+ return Collections.unmodifiableCollection(regions.get(isoCode));
+ } else {
+ throw new IllegalArgumentException(String.format("Country with ISO code '%s' does not exist.", isoCode));
+ }
+ }
+
+ @Override
+ public Collection getCities(String regionCode) {
+ if (cities.containsKey(regionCode)) {
+ return Collections.unmodifiableCollection(cities.get(regionCode));
+ } else {
+ throw new IllegalArgumentException(String.format("Region with code '%s' does not exist.", regionCode));
+ }
+ }
+
+ private void parseCountryDescriptions() {
+ // temporary map of region code / region
+ final Map tempRegions = new HashMap<>();
+ final ResourceBundle countryDescriptions = resourceUtil.getCountryDescriptions(Locale.getDefault());
+ for (String property : Collections.list(countryDescriptions.getKeys())) {
+ final String[] split = property.split("\\.");
+ if (split.length > COUNTRY_INDEX) {
+ final String countryCode = split[COUNTRY_INDEX].toLowerCase();
+ switch (split.length) {
+ case COUNTRY_INDEX + 1:
+ countries.put(countryCode, new Country(countryCode));
+ break;
+ case REGION_INDEX + 1:
+ final Region region = new Region(countryCode, split[REGION_INDEX].toLowerCase());
+ if (regions.containsKey(region.getISOCode())) {
+ regions.get(region.getISOCode()).add(region);
+ } else {
+ List localRegions = new ArrayList<>(0);
+ localRegions.add(region);
+ regions.put(region.getISOCode(), localRegions);
+ }
+ if (countries.containsKey(region.getISOCode())) {
+ countries.get(region.getISOCode()).addRegion(region);
+ }
+ tempRegions.put(region.getCode(), region);
+ break;
+ case CITY_INDEX + 1:
+ final City city = new City(countryCode, split[REGION_INDEX].toLowerCase(),
+ split[CITY_INDEX].toLowerCase());
+ if (cities.containsKey(city.getRegionCode())) {
+ cities.get(city.getRegionCode()).add(city);
+ } else {
+ List localCities = new ArrayList<>(0);
+ localCities.add(city);
+ cities.put(city.getRegionCode(), localCities);
+ }
+ if (tempRegions.containsKey(city.getRegionCode())) {
+ tempRegions.get(city.getRegionCode()).addCity(city);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/jollyday/util/ResourceUtil.java b/src/main/java/de/jollyday/util/ResourceUtil.java
index d22910e7..3b882519 100644
--- a/src/main/java/de/jollyday/util/ResourceUtil.java
+++ b/src/main/java/de/jollyday/util/ResourceUtil.java
@@ -16,7 +16,12 @@
package de.jollyday.util;
import java.net.URL;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -32,6 +37,9 @@ public class ResourceUtil {
* Property prefix for country descriptions.
*/
private static final String COUNTRY_PROPERTY_PREFIX = "country.description";
+ public static final int COUNTRY_INDEX = 2;
+ public static final int REGION_INDEX = 3;
+ public static final int CITY_INDEX = 4;
/**
* Property prefix for holiday descriptions.
*/
@@ -66,7 +74,8 @@ public class ResourceUtil {
* The description read with the default locale.
*
* @return holiday description using default locale.
- * @param key a {@link java.lang.String} object.
+ * @param key
+ * a {@link java.lang.String} object.
*/
public String getHolidayDescription(String key) {
return getHolidayDescription(Locale.getDefault(), key);
@@ -75,9 +84,11 @@ public String getHolidayDescription(String key) {
/**
* The description read with the provided locale.
*
- * @param locale a {@link java.util.Locale} object.
+ * @param locale
+ * a {@link java.util.Locale} object.
* @return holiday description using the provided locale.
- * @param key a {@link java.lang.String} object.
+ * @param key
+ * a {@link java.lang.String} object.
*/
public String getHolidayDescription(Locale locale, String key) {
return getDescription(HOLIDAY_PROPERTY_PREFIX + "." + key, getHolidayDescriptions(locale));
@@ -89,7 +100,8 @@ public String getHolidayDescription(Locale locale, String key) {
*
*
* @return the description
- * @param key a {@link java.lang.String} object.
+ * @param key
+ * a {@link java.lang.String} object.
*/
public String getCountryDescription(String key) {
return getCountryDescription(Locale.getDefault(), key);
@@ -98,8 +110,10 @@ public String getCountryDescription(String key) {
/**
* Returns the hierarchies description text from the resource bundle.
*
- * @param l Locale to return the description text for.
- * @param key a {@link java.lang.String} object.
+ * @param l
+ * Locale to return the description text for.
+ * @param key
+ * a {@link java.lang.String} object.
* @return Description text
*/
public String getCountryDescription(Locale l, String key) {
@@ -119,8 +133,8 @@ public Set getISOCodes() {
ResourceBundle countryDescriptions = getCountryDescriptions(Locale.getDefault());
for (String property : Collections.list(countryDescriptions.getKeys())) {
String[] split = property.split("\\.");
- if (split.length > 2) {
- codes.add(split[2].toLowerCase());
+ if (split.length > COUNTRY_INDEX) {
+ codes.add(split[COUNTRY_INDEX].toLowerCase());
}
}
return codes;
@@ -130,8 +144,10 @@ public Set getISOCodes() {
* Returns the description from the resource bundle if the key is contained.
* It will return 'undefined' otherwise.
*
- * @param key the key to get the description from
- * @param bundle the bundle to get the description
+ * @param key
+ * the key to get the description from
+ * @param bundle
+ * the bundle to get the description
* @return description the description behind the key
*/
private String getDescription(String key, final ResourceBundle bundle) {
@@ -145,7 +161,8 @@ private String getDescription(String key, final ResourceBundle bundle) {
* Returns the eventually cached ResourceBundle for the holiday
* descriptions.
*
- * @param l Locale to retrieve the descriptions for.
+ * @param l
+ * Locale to retrieve the descriptions for.
* @return ResourceBundle containing the descriptions for the locale.
*/
private ResourceBundle getHolidayDescriptions(Locale l) {
@@ -156,17 +173,19 @@ private ResourceBundle getHolidayDescriptions(Locale l) {
* Returns the eventually cached ResourceBundle for the holiday
* descriptions.
*
- * @param l Locale to retrieve the descriptions for.
+ * @param l
+ * Locale to retrieve the descriptions for.
* @return ResourceBundle containing the descriptions for the locale.
*/
- private ResourceBundle getCountryDescriptions(Locale l) {
+ public ResourceBundle getCountryDescriptions(Locale l) {
return getResourceBundle(l, COUNTRY_DESCRIPTIONS_CACHE, COUNTRY_DESCRIPTIONS_FILE_PREFIX);
}
/**
* Returns the eventually cached ResourceBundle for the descriptions.
*
- * @param l Locale to retrieve the descriptions for.
+ * @param l
+ * Locale to retrieve the descriptions for.
* @return ResourceBundle containing the descriptions for the locale.
*/
private ResourceBundle getResourceBundle(Locale l, Map resourceCache, String filePrefix) {
@@ -180,7 +199,8 @@ private ResourceBundle getResourceBundle(Locale l, Map r
/**
* Returns the resource by URL.
*
- * @param resourceName the name/path of the resource to load
+ * @param resourceName
+ * the name/path of the resource to load
* @return the URL to the resource
*/
public URL getResource(String resourceName) {
@@ -188,7 +208,7 @@ public URL getResource(String resourceName) {
URL resource = classLoadingUtil.getClassloader().getResource(resourceName);
return resource == null ? this.getClass().getClassLoader().getResource(resourceName) : resource;
} catch (Exception e) {
- throw new IllegalStateException("Cannot load resource: " + resourceName, e);
+ throw new IllegalStateException("Cannot load resource: " + resourceName, e);
}
}
diff --git a/src/main/resources/descriptions/country_descriptions_de.properties b/src/main/resources/descriptions/country_descriptions_de.properties
index 44bcc5d4..4cc167a2 100644
--- a/src/main/resources/descriptions/country_descriptions_de.properties
+++ b/src/main/resources/descriptions/country_descriptions_de.properties
@@ -28,7 +28,7 @@ country.description.au.nt = N\u00F6rdliches Territorium
country.description.au.qld = Queensland
country.description.au.sa = S\u00FCd-Australien
country.description.au.tas = Tasmanien
-country.description.au.tas.ho = Hobard Area
+country.description.au.tas.ho = Hobart
country.description.au.tas.nh = Non-Hobard Area
country.description.au.vic = Victoria
country.description.au.wa = West-Australien
diff --git a/src/test/java/de/jollyday/CityTest.java b/src/test/java/de/jollyday/CityTest.java
new file mode 100644
index 00000000..d020419b
--- /dev/null
+++ b/src/test/java/de/jollyday/CityTest.java
@@ -0,0 +1,32 @@
+package de.jollyday;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CityTest {
+
+ private static final String COUNTRY_AUSTRALIA_KEY = "au";
+ private static final String REGION_TASMANIA_KEY = "tas";
+ private static final String CITY_HOBARD_AREA_KEY = "ho";
+
+ @Before
+ public void setup() {
+ Locale.setDefault(Locale.ENGLISH);
+ }
+
+ @Test
+ public void testI18nWorksCorrectly() {
+ City region = new City(COUNTRY_AUSTRALIA_KEY, REGION_TASMANIA_KEY, CITY_HOBARD_AREA_KEY);
+ Assert.assertEquals(CITY_HOBARD_AREA_KEY, region.getCode());
+ Assert.assertEquals(REGION_TASMANIA_KEY, region.getRegionCode());
+ Assert.assertEquals(COUNTRY_AUSTRALIA_KEY, region.getISOCode());
+ Assert.assertEquals(COUNTRY_AUSTRALIA_KEY + "." + REGION_TASMANIA_KEY + "." + CITY_HOBARD_AREA_KEY,
+ region.getPropertiesKey());
+
+ Assert.assertEquals("Hobard Area", region.getDescription());
+ Assert.assertEquals("Hobart", region.getDescription(Locale.GERMAN));
+ }
+}
diff --git a/src/test/java/de/jollyday/CountryTest.java b/src/test/java/de/jollyday/CountryTest.java
new file mode 100644
index 00000000..616edcca
--- /dev/null
+++ b/src/test/java/de/jollyday/CountryTest.java
@@ -0,0 +1,27 @@
+package de.jollyday;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CountryTest {
+
+ private static final String COUNTRY_AUSTRALIA_KEY = "au";
+
+ @Before
+ public void setup() {
+ Locale.setDefault(Locale.ENGLISH);
+ }
+
+ @Test
+ public void testI18nWorksCorrectly() {
+ Country country = new Country(COUNTRY_AUSTRALIA_KEY);
+ Assert.assertEquals(COUNTRY_AUSTRALIA_KEY, country.getISOCode());
+ Assert.assertEquals(COUNTRY_AUSTRALIA_KEY, country.getPropertiesKey());
+
+ Assert.assertEquals("Australia", country.getDescription());
+ Assert.assertEquals("Australien", country.getDescription(Locale.GERMAN));
+ }
+}
diff --git a/src/test/java/de/jollyday/RegionTest.java b/src/test/java/de/jollyday/RegionTest.java
new file mode 100644
index 00000000..b4015cbd
--- /dev/null
+++ b/src/test/java/de/jollyday/RegionTest.java
@@ -0,0 +1,29 @@
+package de.jollyday;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RegionTest {
+
+ private static final String COUNTRY_AUSTRALIA_KEY = "au";
+ private static final String REGION_TASMANIA_KEY = "tas";
+
+ @Before
+ public void init() {
+ Locale.setDefault(Locale.ENGLISH);
+ }
+
+ @Test
+ public void testI18nWorksCorrectly() {
+ Region region = new Region(COUNTRY_AUSTRALIA_KEY, REGION_TASMANIA_KEY);
+ Assert.assertEquals(REGION_TASMANIA_KEY, region.getCode());
+ Assert.assertEquals(COUNTRY_AUSTRALIA_KEY, region.getISOCode());
+ Assert.assertEquals(COUNTRY_AUSTRALIA_KEY + "." + REGION_TASMANIA_KEY, region.getPropertiesKey());
+
+ Assert.assertEquals("Tasmania", region.getDescription());
+ Assert.assertEquals("Tasmanien", region.getDescription(Locale.GERMAN));
+ }
+}
diff --git a/src/test/java/de/jollyday/configuration/impl/CountryDescriptionProviderImplTest.java b/src/test/java/de/jollyday/configuration/impl/CountryDescriptionProviderImplTest.java
new file mode 100644
index 00000000..f9179103
--- /dev/null
+++ b/src/test/java/de/jollyday/configuration/impl/CountryDescriptionProviderImplTest.java
@@ -0,0 +1,51 @@
+package de.jollyday.configuration.impl;
+
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import de.jollyday.City;
+import de.jollyday.Country;
+import de.jollyday.Region;
+import de.jollyday.util.ResourceUtil;
+
+public class CountryDescriptionProviderImplTest {
+
+ private static final String COUNTRY_AUSTRALIA_KEY = "au";
+ private static final String REGION_TASMANIA_KEY = "tas";
+ private static final String CITY_HOBARD_AREA_KEY = "ho";
+
+ private CountryDescriptionProviderImpl provider = new CountryDescriptionProviderImpl();
+ private ResourceUtil resourceUtil = new ResourceUtil();
+
+ @Test
+ public void testParsingOfCountriesWorksCorrecly() {
+ Assert.assertNotEquals(0, provider.countries);
+ Assert.assertEquals(resourceUtil.getISOCodes().size(), provider.countries.size());
+
+ Collection countries = provider.getCountries();
+ Assert.assertEquals(provider.countries.size(), countries.size());
+
+ Assert.assertTrue(
+ countries.stream().filter(c -> c.getISOCode().equals(COUNTRY_AUSTRALIA_KEY)).findFirst().isPresent());
+ }
+
+ public void testParsingOfRegionsWorksCorrectly() {
+ Assert.assertNotEquals(0, provider.regions);
+
+ Collection regions = provider.getRegions(COUNTRY_AUSTRALIA_KEY);
+ Assert.assertEquals(8, regions.size());
+
+ Assert.assertTrue(regions.contains(new Region(COUNTRY_AUSTRALIA_KEY, REGION_TASMANIA_KEY)));
+ }
+
+ public void testParsingOfCitiesWorksCorrectly() {
+ Assert.assertNotEquals(0, provider.cities);
+
+ Collection cities = provider.getCities(REGION_TASMANIA_KEY);
+ Assert.assertEquals(2, cities.size());
+
+ Assert.assertTrue(cities.contains(new City(COUNTRY_AUSTRALIA_KEY, REGION_TASMANIA_KEY, CITY_HOBARD_AREA_KEY)));
+ }
+}