Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@

import java.text.MessageFormat;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
* Messages class for internationalization. Thread-safe via ThreadLocal.
*
* <p>This class provides two API styles:
* <ul>
* <li><b>Stateless</b> — {@link #getString(Locale, String)} and
* {@link #getString(Locale, String, Object...)} require an explicit
* {@code Locale} parameter and never touch thread-local state.
* These are the preferred path for new code.</li>
* <li><b>Stateful (legacy)</b> — {@link #getString(String)} and
* {@link #getString(String, Object...)} read from a per-thread
* {@link ResourceBundle} controlled by {@link #setLocale(Locale)}.
* Scheduled for removal in a future major release.</li>
* </ul>
*
* All lookups degrade gracefully: if a key is missing in the requested bundle
* (or any ancestor), the key itself is returned instead of throwing.
*
* @author mivek
*/
public final class Messages {
Expand All @@ -21,7 +37,7 @@ public final class Messages {
/**
* Private constructor.
*/
private Messages() {}
private Messages() { }

/**
* @return the Messages instance.
Expand All @@ -34,7 +50,10 @@ public static Messages getInstance() {
* Sets the locale of the bundle for the current thread.
*
* @param locale the locale to set.
* @deprecated Use {@link #getString(Locale, String)} instead.
* Scheduled for removal in a future major release.
*/
@Deprecated
public void setLocale(final Locale locale) {
bundleHolder.set(ResourceBundle.getBundle(BUNDLE_NAME, locale));
}
Expand All @@ -44,25 +63,81 @@ public void setLocale(final Locale locale) {
*
* <p>Must be called in thread-pool environments (e.g., servlets, Spring)
* after each request to prevent locale leakage between tasks on the same thread.
*
* @deprecated Use {@link #getString(Locale, String)} instead.
* Scheduled for removal in a future major release.
*/
@Deprecated
public void clearLocale() {
bundleHolder.remove();
}

/**
* @param message the string to get
* @return the translation of message
* Returns a localized string for the given key using the thread-local locale.
*
* @param message the key to look up.
* @return the translated string.
* @throws java.util.MissingResourceException if the key is not found.
*/
public String getString(final String message) {
return bundleHolder.get().getString(message);
}

/**
* @param message the translation to get
* @param arguments the arguments to fill
* @return the translation of the message with the arguments.
* Returns a formatted localized string for the given key and arguments
* using the thread-local locale.
*
* @param message the key to look up.
* @param arguments the arguments to fill into the message pattern.
* @return the formatted translated string.
* @throws java.util.MissingResourceException if the key is not found.
*/
public String getString(final String message, final Object... arguments) {
return MessageFormat.format(getString(message), arguments);
}

// ---- Stateless overloads (preferred API) ----

/**
* Returns a localized string for the given key and locale.
*
* <p>This method does <b>not</b> use the thread-local locale. It fetches
* a {@link ResourceBundle} directly for the given locale, making it safe
* for concurrent and multi-locale use.
*
* @param locale the locale to use.
* @param key the key to look up.
* @return the translated string, or the key itself if not found.
*/
public String getString(final Locale locale, final String key) {
return getStringSafe(ResourceBundle.getBundle(BUNDLE_NAME, locale), key);
}

/**
* Returns a formatted localized string for the given key, locale, and arguments.
*
* <p>This method does <b>not</b> use the thread-local locale. It fetches
* a {@link ResourceBundle} directly for the given locale, making it safe
* for concurrent and multi-locale use.
*
* @param locale the locale to use.
* @param key the key to look up.
* @param arguments the arguments to fill into the message pattern.
* @return the formatted translated string, or the key if not found.
*/
public String getString(final Locale locale, final String key, final Object... arguments) {
return MessageFormat.format(getString(locale, key), arguments);
}

/**
* Safely looks up a key from a ResourceBundle, returning the key itself
* on {@link MissingResourceException}.
*/
private static String getStringSafe(final ResourceBundle bundle, final String key) {
try {
return bundle.getString(key);
} catch (final MissingResourceException e) {
return key;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,167 @@ ToString.wind.max.variation=maximale Windänderung
ToString.wind.speed=Geschwindigkeit
ToString.wind.unit=Einheit

# Missing translation - using English fallback
CloudQuantity.NCD=no cloud detected
# Missing translation - using English fallback
CloudType.AC=Altocumulus
# Missing translation - using English fallback
CloudType.AS=Altostratus
# Missing translation - using English fallback
CloudType.CB=Cumulonimbus
# Missing translation - using English fallback
CloudType.CI=Cirrus
# Missing translation - using English fallback
CloudType.CS=Cirrostratus
# Missing translation - using English fallback
CloudType.CU=Cumulus
# Missing translation - using English fallback
CloudType.NS=Nimbostratus
# Missing translation - using English fallback
CloudType.SC=Stratocumulus
# Missing translation - using English fallback
CloudType.ST=Stratus
# Missing translation - using English fallback
Converter.W=West
# Missing translation - using English fallback
DepositBrakingCapacity.default=friction coefficient of {0}
# Missing translation - using English fallback
DepositThickness.92=10 cm
# Missing translation - using English fallback
DepositThickness.93=15 cm
# Missing translation - using English fallback
DepositThickness.94=20 cm
# Missing translation - using English fallback
DepositThickness.95=25 cm
# Missing translation - using English fallback
DepositThickness.96=30 cm
# Missing translation - using English fallback
DepositThickness.97=35 cm
# Missing translation - using English fallback
DepositThickness.default={0} mm
# Missing translation - using English fallback
DepositType.SLUSH=slush
# Missing translation - using English fallback
ErrorCode.IncompleteRunwayInformation=The runway information is incomplete and cannot be parsed.
# Missing translation - using English fallback
Flag.AMD=amended TAF
# Missing translation - using English fallback
Flag.AUTO=automated METAR
# Missing translation - using English fallback
Flag.CNL=canceled TAF
# Missing translation - using English fallback
Flag.COR=corrected METAR/TAF
# Missing translation - using English fallback
Flag.NIL=no data
# Missing translation - using English fallback
IcingIntensity.0=Trace Icing or None
# Missing translation - using English fallback
IcingIntensity.1=Light Mixed Icing
# Missing translation - using English fallback
IcingIntensity.2=Light Rime Icing In Cloud
# Missing translation - using English fallback
IcingIntensity.3=Light Clear Icing In Precipitation
# Missing translation - using English fallback
IcingIntensity.4=Moderate Mixed Icing
# Missing translation - using English fallback
IcingIntensity.5=Moderate Rime Icing In Cloud
# Missing translation - using English fallback
IcingIntensity.6=Moderate Clear Icing In Precipitation
# Missing translation - using English fallback
IcingIntensity.7=Severe Mixed Icing
# Missing translation - using English fallback
IcingIntensity.8=Severe Rime Icing In Cloud
# Missing translation - using English fallback
IcingIntensity.9=Severe Clear Icing In Precipitation
# Missing translation - using English fallback
Intensity.RE=Recent
# Missing translation - using English fallback
Remark.ALQDS=all quadrants
# Missing translation - using English fallback
Remark.Barometer.0=Increase, then decrease
# Missing translation - using English fallback
Remark.Barometer.1=Increase, then steady, or increase then Increase more slowly
# Missing translation - using English fallback
Remark.Barometer.2=steady or unsteady increase
# Missing translation - using English fallback
Remark.Barometer.3=Decrease or steady, then increase; or increase then increase more rapidly
# Missing translation - using English fallback
Remark.Barometer.4=Steady
# Missing translation - using English fallback
Remark.Barometer.5=Decrease, then increase
# Missing translation - using English fallback
Remark.Barometer.6=Decrease then steady; or decrease then decrease more slowly
# Missing translation - using English fallback
Remark.Barometer.7=Steady or unsteady decrease
# Missing translation - using English fallback
Remark.Barometer.8=Steady or increase, then decrease; or decrease then decrease more rapidly
# Missing translation - using English fallback
Remark.DSNT=distant
# Missing translation - using English fallback
Remark.Hourly.Maximum.Minimum.Temperature=24-hour maximum temperature of {0}°C and 24-hour minimum temperature of {1}°C
# Missing translation - using English fallback
Remark.Hourly.Maximum.Temperature=6-hourly maximum temperature of {0}°C
# Missing translation - using English fallback
Remark.Hourly.Minimum.Temperature=6-hourly minimum temperature of {0}°C
# Missing translation - using English fallback
Remark.Hourly.Temperature=hourly temperature of {0}°C
# Missing translation - using English fallback
Remark.Hourly.Temperature.Dew.Point=hourly temperature of {0}°C and dew point of {1}°C
# Missing translation - using English fallback
Remark.Ice.Accretion.Amount={0}/100 of an inch of ice accretion in the past {1} hour(s)
# Missing translation - using English fallback
Remark.LTG=lightning
# Missing translation - using English fallback
Remark.Precipitation.Amount.24={0} inches of precipitation fell in the last 24 hours
# Missing translation - using English fallback
Remark.Precipitation.Amount.3.6={1} inches of precipitation fell in the last {0} hours
# Missing translation - using English fallback
Remark.Precipitation.Amount.Hourly={0}/100 of an inch of precipitation fell in the last hour
# Missing translation - using English fallback
Remark.Precipitation.Beg={0} {1} beginning at {2}\:{3}
# Missing translation - using English fallback
Remark.Precipitation.End={0} {1} ending at {2}\:{3}
# Missing translation - using English fallback
Remark.Pressure.Tendency=of {0} hectopascals in the past 3 hours
# Missing translation - using English fallback
Remark.Snow.Depth=snow depth of {0} inches
# Missing translation - using English fallback
Remark.Sunshine.Duration={0} minutes of sunshine
# Missing translation - using English fallback
Remark.Water.Equivalent.Snow.Ground=water equivalent of {0} inches of snow
# Missing translation - using English fallback
ReportType.METAR=Routine report
# Missing translation - using English fallback
ReportType.SPECI=Special report
# Missing translation - using English fallback
ToString.baseHeight=base layer in feet
# Missing translation - using English fallback
ToString.depth=layer depth in feet
# Missing translation - using English fallback
ToString.flags=flags
# Missing translation - using English fallback
ToString.runway.unit=runway visual range unit
# Missing translation - using English fallback
TurbulenceIntensity.0=None
# Missing translation - using English fallback
TurbulenceIntensity.1=Light turbulence
# Missing translation - using English fallback
TurbulenceIntensity.2=Moderate turbulence in clear air, occasional
# Missing translation - using English fallback
TurbulenceIntensity.3=Moderate turbulence in clear air, frequent
# Missing translation - using English fallback
TurbulenceIntensity.4=Moderate turbulence in cloud, occasional
# Missing translation - using English fallback
TurbulenceIntensity.5=Moderate turbulence in cloud, frequent
# Missing translation - using English fallback
TurbulenceIntensity.6=Severe turbulence in clear air, occasional
# Missing translation - using English fallback
TurbulenceIntensity.7=Severe turbulence in clear air, frequent
# Missing translation - using English fallback
TurbulenceIntensity.8=Severe turbulence in cloud, occasional
# Missing translation - using English fallback
TurbulenceIntensity.9=Severe turbulence in cloud, frequent
# Missing translation - using English fallback
TurbulenceIntensity.X=Extreme turbulence
# Missing translation - using English fallback
WeatherChangeType.INTER=Intermittent
Loading
Loading