diff --git a/metarParser-commons/src/main/java/io/github/mivek/internationalization/Messages.java b/metarParser-commons/src/main/java/io/github/mivek/internationalization/Messages.java index f48ed438..731629f6 100644 --- a/metarParser-commons/src/main/java/io/github/mivek/internationalization/Messages.java +++ b/metarParser-commons/src/main/java/io/github/mivek/internationalization/Messages.java @@ -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. * + *
This class provides two API styles: + *
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. + * + *
This method does not 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. + * + *
This method does not 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;
+ }
+ }
}
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_de.properties b/metarParser-commons/src/main/resources/internationalization/messages_de.properties
index 91a410d5..409cd928 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_de.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_de.properties
@@ -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
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_es.properties b/metarParser-commons/src/main/resources/internationalization/messages_es.properties
index 020b020b..9601c5c2 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_es.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_es.properties
@@ -136,3 +136,324 @@ ToString.wind.direction=dirección
ToString.wind.direction.degrees=dirección (grados)
TurbulenceIntensity.X=Turbulencia extrema
+
+# Missing translation - using English fallback
+CloudQuantity.BKN=broken
+# Missing translation - using English fallback
+CloudQuantity.FEW=few
+# Missing translation - using English fallback
+CloudQuantity.NCD=no cloud detected
+# Missing translation - using English fallback
+CloudQuantity.SCT=scattered
+# Missing translation - using English fallback
+Converter.D=decreasing
+# Missing translation - using English fallback
+Converter.ENE=East North East
+# Missing translation - using English fallback
+Converter.ESE=East South East
+# Missing translation - using English fallback
+Converter.NNE=North North East
+# Missing translation - using English fallback
+Converter.NNW=North North West
+# Missing translation - using English fallback
+Converter.NSC=no significant change
+# Missing translation - using English fallback
+Converter.SSE=South South East
+# Missing translation - using English fallback
+Converter.SSW=South South West
+# Missing translation - using English fallback
+Converter.SW=South West
+# Missing translation - using English fallback
+Converter.U=up rising
+# Missing translation - using English fallback
+Converter.WNW=West North West
+# Missing translation - using English fallback
+Converter.WSW=West South West
+# Missing translation - using English fallback
+DepositBrakingCapacity.91=poor
+# Missing translation - using English fallback
+DepositBrakingCapacity.92=poor/medium
+# Missing translation - using English fallback
+DepositBrakingCapacity.93=medium
+# Missing translation - using English fallback
+DepositBrakingCapacity.94=medium/good
+# Missing translation - using English fallback
+DepositBrakingCapacity.95=good
+# Missing translation - using English fallback
+DepositBrakingCapacity.99=figures unreliable
+# Missing translation - using English fallback
+DepositBrakingCapacity.default=friction coefficient of {0}
+# Missing translation - using English fallback
+Descriptive.BC=patches
+# Missing translation - using English fallback
+Descriptive.BL=blowing
+# Missing translation - using English fallback
+Descriptive.DR=low drifting
+# Missing translation - using English fallback
+Descriptive.FZ=freezing
+# Missing translation - using English fallback
+Descriptive.MI=shallow
+# Missing translation - using English fallback
+Descriptive.SH=showers of
+# Missing translation - using English fallback
+Error.prefix=An error occured. Error code n°
+# Missing translation - using English fallback
+ErrorCode.AirportNotFound=The airport was not found for this message.
+# Missing translation - using English fallback
+ErrorCode.IncompleteRunwayInformation=The runway information is incomplete and cannot be parsed.
+# 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.+=Heavy
+# Missing translation - using English fallback
+Intensity.-=Light
+# Missing translation - using English fallback
+Intensity.VC=In the vicinity
+# Missing translation - using English fallback
+Phenomenon.BR=mist
+# Missing translation - using English fallback
+Phenomenon.DU=widespread dust
+# Missing translation - using English fallback
+Phenomenon.DZ=drizzle
+# Missing translation - using English fallback
+Phenomenon.FC=funnel cloud
+# Missing translation - using English fallback
+Phenomenon.GR=hail
+# Missing translation - using English fallback
+Phenomenon.GS=small hail and/or snow pellets
+# Missing translation - using English fallback
+Phenomenon.HZ=haze
+# Missing translation - using English fallback
+Phenomenon.IC=ice crystals
+# Missing translation - using English fallback
+Phenomenon.PL=ice pellets
+# Missing translation - using English fallback
+Phenomenon.PO=dust or sand whirls
+# Missing translation - using English fallback
+Phenomenon.PY=spray
+# Missing translation - using English fallback
+Phenomenon.SG=snow grains
+# Missing translation - using English fallback
+Phenomenon.SQ=squall
+# Missing translation - using English fallback
+Remark.HVY=heavy
+# Missing translation - using English fallback
+Remark.Hail=largest hailstones with a diameter of {0} inches
+# Missing translation - using English fallback
+Remark.Hail.LesserThan=largest hailstones with a diameter less than {0} inches
+# 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.LGT=light
+# Missing translation - using English fallback
+Remark.LTG=lightning
+# Missing translation - using English fallback
+Remark.MOD=moderate
+# Missing translation - using English fallback
+Remark.ON=on
+# Missing translation - using English fallback
+Remark.Obscuration={0} layer at {1} feet composed of {2}
+# Missing translation - using English fallback
+Remark.PRESFR=pressure falling rapidly
+# Missing translation - using English fallback
+Remark.PRESRR=pressure rising rapidly
+# Missing translation - using English fallback
+Remark.PeakWind=peak wind of {1} knots from {0} degrees at {2}\:{3}
+# 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.Beg.End={0} {1} beginning at {2}\:{3} ending at {4}\:{5}
+# 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.SLPNO=sea level pressure not available
+# Missing translation - using English fallback
+Remark.Sea.Level.Pressure=sea level pressure of {0} HPa
+# Missing translation - using English fallback
+Remark.Second.Location.Visibility=visibility of {0} SM mesured by a second sensor located at {1}
+# Missing translation - using English fallback
+Remark.Sector.Visibility=visibility of {1} SM in the {0} direction
+# Missing translation - using English fallback
+Remark.Snow.Depth=snow depth of {0} inches
+# Missing translation - using English fallback
+Remark.Snow.Increasing.Rapidly=snow depth increase of {0} inches in the past hour with a total depth on the ground of {1} inches
+# Missing translation - using English fallback
+Remark.Snow.Pellets={0} snow pellets
+# Missing translation - using English fallback
+Remark.Sunshine.Duration={0} minutes of sunshine
+# Missing translation - using English fallback
+Remark.Surface.Visibility=surface visibility of {0} statute miles
+# Missing translation - using English fallback
+Remark.Thunderstorm.Location=thunderstorm {0} of the station
+# Missing translation - using English fallback
+Remark.Thunderstorm.Location.Moving=thunderstorm {0} of the station moving towards {1}
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.BegEnd={0} beginning at {1}\:{2} ending at {3}\:{4} {5} SM {6} of the station
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.Beginning={0} beginning at {1}\:{2} {3} SM {4} of the station
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.Ending={0} ending at {1}\:{2} {3} SM {4} of the station
+# Missing translation - using English fallback
+Remark.Tower.Visibility=control tower visibility of {0} statute miles
+# Missing translation - using English fallback
+Remark.VIRGA=virga
+# Missing translation - using English fallback
+Remark.Variable.Prevailing.Visibility=variable prevailing visibility between {0} and {1} SM
+# Missing translation - using English fallback
+Remark.Variable.Sky.Condition=cloud layer varying between {0} and {1}
+# Missing translation - using English fallback
+Remark.Variable.Sky.Condition.Height=cloud layer at {0} feet varying between {1} and {2}
+# Missing translation - using English fallback
+Remark.Virga.Direction=virga {0} from the station
+# Missing translation - using English fallback
+Remark.WATERSPOUT=waterspout
+# Missing translation - using English fallback
+Remark.Water.Equivalent.Snow.Ground=water equivalent of {0} inches of snow
+# Missing translation - using English fallback
+Remark.WindShift=wind shift at {0}\:{1}
+# Missing translation - using English fallback
+Remark.WindShift.FROPA=wind shift accompanied by frontal passage at {0}\:{1}
+# Missing translation - using English fallback
+ReportType.METAR=Routine report
+# Missing translation - using English fallback
+ReportType.SPECI=Special report
+# Missing translation - using English fallback
+TimeIndicator.AT=at
+# Missing translation - using English fallback
+ToString.altimeter=altimeter (hPa)
+# Missing translation - using English fallback
+ToString.amendment=amendment
+# Missing translation - using English fallback
+ToString.auto=auto
+# Missing translation - using English fallback
+ToString.baseHeight=base layer in feet
+# Missing translation - using English fallback
+ToString.cavok=cavok
+# Missing translation - using English fallback
+ToString.deposit.braking=braking capacity
+# Missing translation - using English fallback
+ToString.deposit.coverage=coverage
+# Missing translation - using English fallback
+ToString.deposit.thickness=thickness
+# Missing translation - using English fallback
+ToString.deposit.type=type of deposit
+# Missing translation - using English fallback
+ToString.depth=layer depth in feet
+# Missing translation - using English fallback
+ToString.descriptive=descriptive
+# Missing translation - using English fallback
+ToString.dew.point=dew point
+# Missing translation - using English fallback
+ToString.end.day.month=end day of the month
+# Missing translation - using English fallback
+ToString.end.hour.day=end hour of the day
+# Missing translation - using English fallback
+ToString.flags=flags
+# Missing translation - using English fallback
+ToString.nosig=nosig
+# Missing translation - using English fallback
+ToString.remark=remarks
+# Missing translation - using English fallback
+ToString.runway.info=runways information
+# Missing translation - using English fallback
+ToString.runway.unit=runway visual range unit
+# Missing translation - using English fallback
+ToString.start.day.month=starting day of the month
+# Missing translation - using English fallback
+ToString.start.hour.day=starting hour of the day
+# Missing translation - using English fallback
+ToString.start.minute=starting minute
+# Missing translation - using English fallback
+ToString.trend=trend
+# Missing translation - using English fallback
+ToString.trends=trends
+# Missing translation - using English fallback
+ToString.vertical.visibility=vertical visibility (ft)
+# Missing translation - using English fallback
+ToString.vertical.visibility.unit=vertical visibility unit
+# Missing translation - using English fallback
+ToString.visibility.main=main visibility
+# Missing translation - using English fallback
+ToString.visibility.max=maximum visibility
+# Missing translation - using English fallback
+ToString.visibility.min=minimum visibility
+# Missing translation - using English fallback
+ToString.visibility.min.direction=minimum visibility direction
+# Missing translation - using English fallback
+ToString.visibility.unit=visibility unit
+# Missing translation - using English fallback
+ToString.weather.conditions=weather conditions
+# Missing translation - using English fallback
+ToString.wind.gusts=gusts
+# Missing translation - using English fallback
+ToString.wind.max.variation=maximal wind variation
+# Missing translation - using English fallback
+ToString.wind.min.variation=minimal wind variation
+# Missing translation - using English fallback
+ToString.wind.speed=speed
+# Missing translation - using English fallback
+ToString.wind.unit=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
+WeatherChangeType.BECMG=Becoming
+# Missing translation - using English fallback
+WeatherChangeType.FM=From
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_fr.properties b/metarParser-commons/src/main/resources/internationalization/messages_fr.properties
index e2991259..86b7336b 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_fr.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_fr.properties
@@ -296,8 +296,5 @@ TurbulenceIntensity.X=Turbulence extrême
ReportType.METAR=Rapport de routine
ReportType.SPECI=Rapport spécial
-
-ReportType.METAR=Metar
-ReportType.SPECI=Special
CloudQuantity.NCD=Aucun nuage détecté
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_it.properties b/metarParser-commons/src/main/resources/internationalization/messages_it.properties
index d70cb043..276b581e 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_it.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_it.properties
@@ -290,3 +290,16 @@ TurbulenceIntensity.7=Forte turbolenza in aria limpida, frequente
TurbulenceIntensity.8=Forte turbolenza in nubi, occasionale
TurbulenceIntensity.9=Forte turbolenza in nubi, frequente
TurbulenceIntensity.X=Estrema turbolenza
+
+# Missing translation - using English fallback
+CloudQuantity.NCD=no cloud detected
+# Missing translation - using English fallback
+ErrorCode.IncompleteRunwayInformation=The runway information is incomplete and cannot be parsed.
+# Missing translation - using English fallback
+Intensity.RE=Recent
+# Missing translation - using English fallback
+ReportType.METAR=Routine report
+# Missing translation - using English fallback
+ReportType.SPECI=Special report
+# Missing translation - using English fallback
+ToString.runway.unit=runway visual range unit
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_pl_PL.properties b/metarParser-commons/src/main/resources/internationalization/messages_pl_PL.properties
index c56c999c..c3475241 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_pl_PL.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_pl_PL.properties
@@ -91,3 +91,413 @@ TimeIndicator.AT=o
TimeIndicator.FM=od
TimeIndicator.TL=do
+# Missing translation - using English fallback
+CloudQuantity.NCD=no cloud detected
+# Missing translation - using English fallback
+Converter.ENE=East North East
+# Missing translation - using English fallback
+Converter.ESE=East South East
+# Missing translation - using English fallback
+Converter.NNE=North North East
+# Missing translation - using English fallback
+Converter.NNW=North North West
+# Missing translation - using English fallback
+Converter.SSE=South South East
+# Missing translation - using English fallback
+Converter.SSW=South South West
+# Missing translation - using English fallback
+Converter.WNW=West North West
+# Missing translation - using English fallback
+Converter.WSW=West South West
+# Missing translation - using English fallback
+DepositBrakingCapacity.//=not reported
+# Missing translation - using English fallback
+DepositBrakingCapacity.91=poor
+# Missing translation - using English fallback
+DepositBrakingCapacity.92=poor/medium
+# Missing translation - using English fallback
+DepositBrakingCapacity.93=medium
+# Missing translation - using English fallback
+DepositBrakingCapacity.94=medium/good
+# Missing translation - using English fallback
+DepositBrakingCapacity.95=good
+# Missing translation - using English fallback
+DepositBrakingCapacity.99=figures unreliable
+# Missing translation - using English fallback
+DepositBrakingCapacity.default=friction coefficient of {0}
+# Missing translation - using English fallback
+DepositCoverage.FROM_11_TO_25=from 11% to 25%
+# Missing translation - using English fallback
+DepositCoverage.FROM_26_TO_50=from 26% to 50%
+# Missing translation - using English fallback
+DepositCoverage.FROM_51_TO_100=from 51% to 100%
+# Missing translation - using English fallback
+DepositCoverage.LESS_10=less than 10%
+# Missing translation - using English fallback
+DepositCoverage.NOT_REPORTED=not reported
+# Missing translation - using English fallback
+DepositThickness.//=not reported
+# Missing translation - using English fallback
+DepositThickness.00=less than 1 mm
+# 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.98=40 cm or more
+# Missing translation - using English fallback
+DepositThickness.99=closed
+# Missing translation - using English fallback
+DepositThickness.default={0} mm
+# Missing translation - using English fallback
+DepositType.CLEAR_DRY=clear and dry
+# Missing translation - using English fallback
+DepositType.COMPACTED_SNOW=compacted or rolled snow
+# Missing translation - using English fallback
+DepositType.DAMP=damp
+# Missing translation - using English fallback
+DepositType.DRY_SNOW=dry snow
+# Missing translation - using English fallback
+DepositType.FROZEN_RIDGES=frozen ruts or ridges
+# Missing translation - using English fallback
+DepositType.ICE=ice
+# Missing translation - using English fallback
+DepositType.NOT_REPORTED=not reported
+# Missing translation - using English fallback
+DepositType.RIME_FROST_COVERED=rime or frost covered
+# Missing translation - using English fallback
+DepositType.SLUSH=slush
+# Missing translation - using English fallback
+DepositType.WET_SNOW=wet snow
+# Missing translation - using English fallback
+DepositType.WET_WATER_PATCHES=wet or water patches
+# 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
+Indicator.M=less than
+# Missing translation - using English fallback
+Indicator.P=greater than
+# Missing translation - using English fallback
+Intensity.RE=Recent
+# Missing translation - using English fallback
+Phenomenon.TS=thunderstorm
+# Missing translation - using English fallback
+Remark.ALQDS=all quadrants
+# Missing translation - using English fallback
+Remark.AO1=automated stations without a precipitation discriminator
+# Missing translation - using English fallback
+Remark.AO2=automated station with a precipitation discriminator
+# Missing translation - using English fallback
+Remark.BASED=based
+# 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.Ceiling.Height=ceiling varying between {0} and {1} feet
+# Missing translation - using English fallback
+Remark.Ceiling.Second.Location=ceiling of {0} feet mesured by a second sensor located at {1}
+# Missing translation - using English fallback
+Remark.DSNT=distant
+# Missing translation - using English fallback
+Remark.FCST=forecast
+# Missing translation - using English fallback
+Remark.FUNNELCLOUD=funnel cloud
+# Missing translation - using English fallback
+Remark.HVY=heavy
+# Missing translation - using English fallback
+Remark.Hail=largest hailstones with a diameter of {0} inches
+# Missing translation - using English fallback
+Remark.Hail.LesserThan=largest hailstones with a diameter less than {0} inches
+# 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.LGT=light
+# Missing translation - using English fallback
+Remark.LTG=lightning
+# Missing translation - using English fallback
+Remark.MOD=moderate
+# Missing translation - using English fallback
+Remark.NXT=next
+# Missing translation - using English fallback
+Remark.ON=on
+# Missing translation - using English fallback
+Remark.Obscuration={0} layer at {1} feet composed of {2}
+# Missing translation - using English fallback
+Remark.PRESFR=pressure falling rapidly
+# Missing translation - using English fallback
+Remark.PRESRR=pressure rising rapidly
+# Missing translation - using English fallback
+Remark.PeakWind=peak wind of {1} knots from {0} degrees at {2}\:{3}
+# 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.Beg.End={0} {1} beginning at {2}\:{3} ending at {4}\:{5}
+# 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.SLPNO=sea level pressure not available
+# Missing translation - using English fallback
+Remark.Sea.Level.Pressure=sea level pressure of {0} HPa
+# Missing translation - using English fallback
+Remark.Second.Location.Visibility=visibility of {0} SM mesured by a second sensor located at {1}
+# Missing translation - using English fallback
+Remark.Sector.Visibility=visibility of {1} SM in the {0} direction
+# Missing translation - using English fallback
+Remark.Snow.Depth=snow depth of {0} inches
+# Missing translation - using English fallback
+Remark.Snow.Increasing.Rapidly=snow depth increase of {0} inches in the past hour with a total depth on the ground of {1} inches
+# Missing translation - using English fallback
+Remark.Snow.Pellets={0} snow pellets
+# Missing translation - using English fallback
+Remark.Sunshine.Duration={0} minutes of sunshine
+# Missing translation - using English fallback
+Remark.Surface.Visibility=surface visibility of {0} statute miles
+# Missing translation - using English fallback
+Remark.TORNADO=tornado
+# Missing translation - using English fallback
+Remark.Thunderstorm.Location=thunderstorm {0} of the station
+# Missing translation - using English fallback
+Remark.Thunderstorm.Location.Moving=thunderstorm {0} of the station moving towards {1}
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.BegEnd={0} beginning at {1}\:{2} ending at {3}\:{4} {5} SM {6} of the station
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.Beginning={0} beginning at {1}\:{2} {3} SM {4} of the station
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.Ending={0} ending at {1}\:{2} {3} SM {4} of the station
+# Missing translation - using English fallback
+Remark.Tower.Visibility=control tower visibility of {0} statute miles
+# Missing translation - using English fallback
+Remark.VIRGA=virga
+# Missing translation - using English fallback
+Remark.Variable.Prevailing.Visibility=variable prevailing visibility between {0} and {1} SM
+# Missing translation - using English fallback
+Remark.Variable.Sky.Condition=cloud layer varying between {0} and {1}
+# Missing translation - using English fallback
+Remark.Variable.Sky.Condition.Height=cloud layer at {0} feet varying between {1} and {2}
+# Missing translation - using English fallback
+Remark.Virga.Direction=virga {0} from the station
+# Missing translation - using English fallback
+Remark.WATERSPOUT=waterspout
+# Missing translation - using English fallback
+Remark.Water.Equivalent.Snow.Ground=water equivalent of {0} inches of snow
+# Missing translation - using English fallback
+Remark.WindShift=wind shift at {0}\:{1}
+# Missing translation - using English fallback
+Remark.WindShift.FROPA=wind shift accompanied by frontal passage at {0}\:{1}
+# Missing translation - using English fallback
+ReportType.METAR=Routine report
+# Missing translation - using English fallback
+ReportType.SPECI=Special report
+# Missing translation - using English fallback
+ToString.airport=airport
+# Missing translation - using English fallback
+ToString.altimeter=altimeter (hPa)
+# Missing translation - using English fallback
+ToString.amendment=amendment
+# Missing translation - using English fallback
+ToString.auto=auto
+# Missing translation - using English fallback
+ToString.baseHeight=base layer in feet
+# Missing translation - using English fallback
+ToString.cavok=cavok
+# Missing translation - using English fallback
+ToString.cloud.unit=cloud height unit
+# Missing translation - using English fallback
+ToString.clouds=clouds
+# Missing translation - using English fallback
+ToString.day.hour=hour of the day
+# Missing translation - using English fallback
+ToString.day.month=day of the month
+# Missing translation - using English fallback
+ToString.deposit.braking=braking capacity
+# Missing translation - using English fallback
+ToString.deposit.coverage=coverage
+# Missing translation - using English fallback
+ToString.deposit.thickness=thickness
+# Missing translation - using English fallback
+ToString.deposit.type=type of deposit
+# Missing translation - using English fallback
+ToString.depth=layer depth in feet
+# Missing translation - using English fallback
+ToString.descriptive=descriptive
+# Missing translation - using English fallback
+ToString.dew.point=dew point
+# Missing translation - using English fallback
+ToString.end.day.month=end day of the month
+# Missing translation - using English fallback
+ToString.end.hour.day=end hour of the day
+# Missing translation - using English fallback
+ToString.flags=flags
+# Missing translation - using English fallback
+ToString.height.feet=height (ft)
+# Missing translation - using English fallback
+ToString.height.meter=height (m)
+# Missing translation - using English fallback
+ToString.height.unit=height unit
+# Missing translation - using English fallback
+ToString.indicator=indicator
+# Missing translation - using English fallback
+ToString.intensity=intensity
+# Missing translation - using English fallback
+ToString.message=original message
+# Missing translation - using English fallback
+ToString.name=name
+# Missing translation - using English fallback
+ToString.nosig=nosig
+# Missing translation - using English fallback
+ToString.phenomenons=phenomenons
+# Missing translation - using English fallback
+ToString.probability=probability
+# Missing translation - using English fallback
+ToString.quantity=quantity
+# Missing translation - using English fallback
+ToString.remark=remarks
+# Missing translation - using English fallback
+ToString.report.time=time of report
+# Missing translation - using English fallback
+ToString.runway.info=runways information
+# Missing translation - using English fallback
+ToString.runway.unit=runway visual range unit
+# Missing translation - using English fallback
+ToString.start.day.month=starting day of the month
+# Missing translation - using English fallback
+ToString.start.hour.day=starting hour of the day
+# Missing translation - using English fallback
+ToString.start.minute=starting minute
+# Missing translation - using English fallback
+ToString.temperature=temperature (°C)
+# Missing translation - using English fallback
+ToString.temperature.max=maximum temperature (°C)
+# Missing translation - using English fallback
+ToString.temperature.min=minimum temperature (°C)
+# Missing translation - using English fallback
+ToString.trend=trend
+# Missing translation - using English fallback
+ToString.trends=trends
+# Missing translation - using English fallback
+ToString.type=type
+# Missing translation - using English fallback
+ToString.vertical.visibility=vertical visibility (ft)
+# Missing translation - using English fallback
+ToString.vertical.visibility.unit=vertical visibility unit
+# Missing translation - using English fallback
+ToString.visibility.main=main visibility
+# Missing translation - using English fallback
+ToString.visibility.max=maximum visibility
+# Missing translation - using English fallback
+ToString.visibility.min=minimum visibility
+# Missing translation - using English fallback
+ToString.visibility.min.direction=minimum visibility direction
+# Missing translation - using English fallback
+ToString.visibility.unit=visibility unit
+# Missing translation - using English fallback
+ToString.weather.conditions=weather conditions
+# Missing translation - using English fallback
+ToString.wind.direction=direction
+# Missing translation - using English fallback
+ToString.wind.direction.degrees=direction (degrees)
+# Missing translation - using English fallback
+ToString.wind.gusts=gusts
+# Missing translation - using English fallback
+ToString.wind.max.variation=maximal wind variation
+# Missing translation - using English fallback
+ToString.wind.min.variation=minimal wind variation
+# Missing translation - using English fallback
+ToString.wind.speed=speed
+# Missing translation - using English fallback
+ToString.wind.unit=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
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_ru_RU.properties b/metarParser-commons/src/main/resources/internationalization/messages_ru_RU.properties
index 046c18df..4add9090 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_ru_RU.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_ru_RU.properties
@@ -292,3 +292,12 @@ TurbulenceIntensity.7=Сильная турбулентность при ясн
TurbulenceIntensity.8=Сильная турбулентности в облаках, время от времени
TurbulenceIntensity.9=Сильная турбулентности в облаках, часто
TurbulenceIntensity.X=Экстремальная турбулентность
+
+# Missing translation - using English fallback
+CloudQuantity.NCD=no cloud detected
+# Missing translation - using English fallback
+ReportType.METAR=Routine report
+# Missing translation - using English fallback
+ReportType.SPECI=Special report
+# Missing translation - using English fallback
+ToString.runway.unit=runway visual range unit
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_tr_TR.properties b/metarParser-commons/src/main/resources/internationalization/messages_tr_TR.properties
index 92de8fd8..3423f8fe 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_tr_TR.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_tr_TR.properties
@@ -253,3 +253,89 @@ ToString.wind.max.variation=maksimum rüzgar değişim
ToString.wind.speed=hız
ToString.wind.unit=birim
+# Missing translation - using English fallback
+CloudQuantity.NCD=no cloud detected
+# 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
+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
+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
diff --git a/metarParser-commons/src/main/resources/internationalization/messages_zh_CN.properties b/metarParser-commons/src/main/resources/internationalization/messages_zh_CN.properties
index 9456ce6a..f3e85dc6 100644
--- a/metarParser-commons/src/main/resources/internationalization/messages_zh_CN.properties
+++ b/metarParser-commons/src/main/resources/internationalization/messages_zh_CN.properties
@@ -249,3 +249,98 @@ TurbulenceIntensity.0=无
TurbulenceIntensity.1=轻度乱流
TurbulenceIntensity.8=云中偶发重度颠簸
TurbulenceIntensity.X=极端乱流
+
+# Missing translation - using English fallback
+CloudQuantity.NCD=no cloud detected
+# Missing translation - using English fallback
+ErrorCode.IncompleteRunwayInformation=The runway information is incomplete and cannot be parsed.
+# 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.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.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.Beg.End={0} {1} beginning at {2}\:{3} ending at {4}\:{5}
+# 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.SLPNO=sea level pressure not available
+# Missing translation - using English fallback
+Remark.Second.Location.Visibility=visibility of {0} SM mesured by a second sensor located at {1}
+# Missing translation - using English fallback
+Remark.Sector.Visibility=visibility of {1} SM in the {0} direction
+# Missing translation - using English fallback
+Remark.Snow.Depth=snow depth of {0} inches
+# Missing translation - using English fallback
+Remark.Snow.Increasing.Rapidly=snow depth increase of {0} inches in the past hour with a total depth on the ground of {1} inches
+# Missing translation - using English fallback
+Remark.Snow.Pellets={0} snow pellets
+# Missing translation - using English fallback
+Remark.Sunshine.Duration={0} minutes of sunshine
+# Missing translation - using English fallback
+Remark.Surface.Visibility=surface visibility of {0} statute miles
+# Missing translation - using English fallback
+Remark.Thunderstorm.Location=thunderstorm {0} of the station
+# Missing translation - using English fallback
+Remark.Thunderstorm.Location.Moving=thunderstorm {0} of the station moving towards {1}
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.BegEnd={0} beginning at {1}\:{2} ending at {3}\:{4} {5} SM {6} of the station
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.Beginning={0} beginning at {1}\:{2} {3} SM {4} of the station
+# Missing translation - using English fallback
+Remark.Tornadic.Activity.Ending={0} ending at {1}\:{2} {3} SM {4} of the station
+# Missing translation - using English fallback
+Remark.Tower.Visibility=control tower visibility of {0} statute miles
+# Missing translation - using English fallback
+Remark.Variable.Prevailing.Visibility=variable prevailing visibility between {0} and {1} SM
+# Missing translation - using English fallback
+Remark.Variable.Sky.Condition=cloud layer varying between {0} and {1}
+# Missing translation - using English fallback
+Remark.Variable.Sky.Condition.Height=cloud layer at {0} feet varying between {1} and {2}
+# Missing translation - using English fallback
+Remark.Virga.Direction=virga {0} from the station
+# Missing translation - using English fallback
+Remark.WindShift.FROPA=wind shift accompanied by frontal passage at {0}\:{1}
+# 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.runway.unit=runway visual range unit
+# 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.9=Severe turbulence in cloud, frequent
diff --git a/metarParser-commons/src/test/java/io/github/mivek/internationalization/MessagesTest.java b/metarParser-commons/src/test/java/io/github/mivek/internationalization/MessagesTest.java
index efb96531..4abbfdad 100644
--- a/metarParser-commons/src/test/java/io/github/mivek/internationalization/MessagesTest.java
+++ b/metarParser-commons/src/test/java/io/github/mivek/internationalization/MessagesTest.java
@@ -1,6 +1,5 @@
package io.github.mivek.internationalization;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@@ -10,23 +9,22 @@
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
+import java.util.MissingResourceException;
import java.util.Properties;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
class MessagesTest {
@Test
void testSetLocale() {
- // Given a french locale
Messages.getInstance().setLocale(Locale.FRENCH);
assertEquals("peu", Messages.getInstance().getString("CloudQuantity.FEW"));
- // WHEN Changing the locale to english
Messages.getInstance().setLocale(Locale.ENGLISH);
- // THEN The locale is changed and so is the message.
assertEquals("few", Messages.getInstance().getString("CloudQuantity.FEW"));
assertEquals("ceiling varying between 5 and 15 feet", Messages.getInstance().getString("Remark.Ceiling.Height", 5, 15));
}
@@ -36,14 +34,46 @@ void testClearLocale() {
Messages.getInstance().setLocale(Locale.FRENCH);
assertEquals("peu", Messages.getInstance().getString("CloudQuantity.FEW"));
Messages.getInstance().clearLocale();
- // After clearing, the JVM default locale is used; the key must still be resolvable.
assertDoesNotThrow(() -> Messages.getInstance().getString("CloudQuantity.FEW"));
}
+ @Test
+ void testGetStringWithLocale() {
+ assertEquals("peu", Messages.getInstance().getString(Locale.FRENCH, "CloudQuantity.FEW"));
+ assertEquals("few", Messages.getInstance().getString(Locale.ENGLISH, "CloudQuantity.FEW"));
+ }
+
+ @Test
+ void testGetStringWithLocaleAndArgs() {
+ assertEquals("variation du plafond entre 5 et 15 pieds",
+ Messages.getInstance().getString(Locale.FRENCH, "Remark.Ceiling.Height", 5, 15));
+ assertEquals("ceiling varying between 5 and 15 feet",
+ Messages.getInstance().getString(Locale.ENGLISH, "Remark.Ceiling.Height", 5, 15));
+ }
+
+ @Test
+ void testMissingKeyReturnsKey() {
+ assertThrows(MissingResourceException.class, () -> Messages.getInstance().getString("NonExistent.Key"));
+ assertEquals("NonExistent.Key", Messages.getInstance().getString(Locale.FRENCH, "NonExistent.Key"));
+ }
+
+ @Test
+ void testMissingKeyWithArgsReturnsKey() {
+ assertThrows(MissingResourceException.class, () -> Messages.getInstance().getString("NonExistent.Key", "arg1"));
+ assertEquals("NonExistent.Key", Messages.getInstance().getString(Locale.FRENCH, "NonExistent.Key", "arg1"));
+ }
+
+ @Test
+ void testStatelessOverloadsDoNotAffectThreadLocale() {
+ Messages.getInstance().setLocale(Locale.FRENCH);
+ assertEquals("peu", Messages.getInstance().getString("CloudQuantity.FEW"));
+ assertEquals("few", Messages.getInstance().getString(Locale.ENGLISH, "CloudQuantity.FEW"));
+ assertEquals("peu", Messages.getInstance().getString("CloudQuantity.FEW"));
+ }
+
@ParameterizedTest
@ValueSource(strings = {"messages_de", "messages_es", "messages_fr", "messages_it",
"messages_pl_PL", "messages_ru_RU", "messages_tr_TR", "messages_zh_CN"})
- @Disabled("Requires all locale bundles to be complete and up-to-date with the base bundle")
void testLocaleContainsAllBaseKeys(final String bundleName) throws IOException {
Properties base = loadProperties("internationalization/messages.properties");
Properties locale = loadProperties("internationalization/" + bundleName + ".properties");
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/CloudQuantity.java b/metarParser-entities/src/main/java/io/github/mivek/enums/CloudQuantity.java
index 0125f453..3d0b70d8 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/CloudQuantity.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/CloudQuantity.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* Enumeration for cloud quantity.
@@ -27,9 +28,21 @@ public enum CloudQuantity {
/** No cloud detected. */
NCD;
-
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("CloudQuantity." + name());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "CloudQuantity." + name());
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/CloudType.java b/metarParser-entities/src/main/java/io/github/mivek/enums/CloudType.java
index a2313af3..ed5dacb0 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/CloudType.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/CloudType.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* Enumeration for cloud type. The first attribute is the code used in the
@@ -32,10 +33,22 @@ public enum CloudType {
/** Stratocumulus. */
SC;
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("CloudType." + name());
+ return toString(Locale.getDefault());
}
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "CloudType." + name());
+ }
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/DepositCoverage.java b/metarParser-entities/src/main/java/io/github/mivek/enums/DepositCoverage.java
index cd0273dc..1f391e6e 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/DepositCoverage.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/DepositCoverage.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* Represents the percentage of the runway covered by the deposit.
@@ -18,9 +19,22 @@ public enum DepositCoverage {
/** 51 to 100%: 4. */
FROM_51_TO_100;
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("DepositCoverage." + name());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "DepositCoverage." + name());
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/DepositType.java b/metarParser-entities/src/main/java/io/github/mivek/enums/DepositType.java
index 1b62f1ce..7c32609e 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/DepositType.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/DepositType.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* Represents the type of deposit on a runway.
@@ -30,9 +31,22 @@ public enum DepositType {
/** Frozen ridges: 9. */
FROZEN_RIDGES;
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("DepositType." + name());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "DepositType." + name());
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/Descriptive.java b/metarParser-entities/src/main/java/io/github/mivek/enums/Descriptive.java
index 11486e4c..1e8d3853 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/Descriptive.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/Descriptive.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
import java.util.regex.Pattern;
/**
@@ -57,8 +58,21 @@ public Pattern getPattern() {
return pattern;
}
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("Descriptive." + shortcut);
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "Descriptive." + shortcut);
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/Flag.java b/metarParser-entities/src/main/java/io/github/mivek/enums/Flag.java
index 2ef27572..a215008b 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/Flag.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/Flag.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* Enumeration class for WeatherCode flags.
@@ -19,8 +20,21 @@ public enum Flag {
/** Null. */
NIL;
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("Flag." + name());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "Flag." + name());
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/IcingIntensity.java b/metarParser-entities/src/main/java/io/github/mivek/enums/IcingIntensity.java
index 7fbbe2bd..66ca5009 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/IcingIntensity.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/IcingIntensity.java
@@ -2,6 +2,7 @@
import io.github.mivek.internationalization.Messages;
import java.util.Arrays;
+import java.util.Locale;
/**
* Intensity level for the Icing.
@@ -40,9 +41,30 @@ public enum IcingIntensity {
this.shortcut = shortcut;
}
+ /**
+ * Returns the shortcut of the intensity.
+ * @return the shortcut string.
+ */
+ public String getShortcut() {
+ return shortcut;
+ }
+
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("IcingIntensity." + shortcut);
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "IcingIntensity." + shortcut);
}
/**
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/Intensity.java b/metarParser-entities/src/main/java/io/github/mivek/enums/Intensity.java
index 7edf0333..48f28a0a 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/Intensity.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/Intensity.java
@@ -2,6 +2,7 @@
import io.github.mivek.internationalization.Messages;
import java.util.Arrays;
+import java.util.Locale;
/**
* Enumeration for indicator.
@@ -32,9 +33,22 @@ public enum Intensity {
this.shortcut = shortcut;
}
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("Intensity." + getShortcut());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "Intensity." + getShortcut());
}
/**
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/Phenomenon.java b/metarParser-entities/src/main/java/io/github/mivek/enums/Phenomenon.java
index 7e0ea34b..b9e34fdb 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/Phenomenon.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/Phenomenon.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
import java.util.regex.Pattern;
/**
@@ -71,9 +72,22 @@ public enum Phenomenon {
this.pattern = Pattern.compile("^" + shortcut);
}
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("Phenomenon." + getShortcut());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "Phenomenon." + getShortcut());
}
/**
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/ReportType.java b/metarParser-entities/src/main/java/io/github/mivek/enums/ReportType.java
index c44bed98..5357741d 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/ReportType.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/ReportType.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* Enumeration class for weather code report types.
@@ -13,8 +14,21 @@ public enum ReportType {
/** Special report. */
SPECI;
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("ReportType." + name());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "ReportType." + name());
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoIndicator.java b/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoIndicator.java
index cae051b4..464e02f3 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoIndicator.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoIndicator.java
@@ -2,6 +2,7 @@
import io.github.mivek.internationalization.Messages;
import java.util.Arrays;
+import java.util.Locale;
/**
* Enumeration to represent the indicator of a RunwayTrend.
@@ -24,9 +25,22 @@ public enum RunwayInfoIndicator {
this.shortcut = shortcut;
}
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("Indicator." + shortcut);
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "Indicator." + shortcut);
}
/**
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoTrend.java b/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoTrend.java
index 00ccfdc4..751e345d 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoTrend.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/RunwayInfoTrend.java
@@ -2,6 +2,7 @@
import io.github.mivek.internationalization.Messages;
import java.util.Arrays;
+import java.util.Locale;
/**
* This class contains the possible trends for a RunwayInfo.
@@ -30,9 +31,22 @@ public enum RunwayInfoTrend {
this.key = key;
}
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("Converter." + key);
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "Converter." + key);
}
/**
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/TimeIndicator.java b/metarParser-entities/src/main/java/io/github/mivek/enums/TimeIndicator.java
index c62dfa02..23c7dfdc 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/TimeIndicator.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/TimeIndicator.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* Enumeration for time indicator in metar trends.
@@ -36,8 +37,21 @@ public String getShortcut() {
return shortcut;
}
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("TimeIndicator." + getShortcut());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "TimeIndicator." + getShortcut());
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/TurbulenceIntensity.java b/metarParser-entities/src/main/java/io/github/mivek/enums/TurbulenceIntensity.java
index cd7b4eb4..2b16d42e 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/TurbulenceIntensity.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/TurbulenceIntensity.java
@@ -2,6 +2,7 @@
import io.github.mivek.internationalization.Messages;
import java.util.Arrays;
+import java.util.Locale;
/**
* Intensity level of the Turbulence.
@@ -42,9 +43,30 @@ public enum TurbulenceIntensity {
this.shortcut = shortcut;
}
+ /**
+ * Returns the shortcut of the intensity.
+ * @return the shortcut string.
+ */
+ public String getShortcut() {
+ return shortcut;
+ }
+
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("TurbulenceIntensity." + shortcut);
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "TurbulenceIntensity." + shortcut);
}
/**
diff --git a/metarParser-entities/src/main/java/io/github/mivek/enums/WeatherChangeType.java b/metarParser-entities/src/main/java/io/github/mivek/enums/WeatherChangeType.java
index 0fcec29b..0936e150 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/enums/WeatherChangeType.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/enums/WeatherChangeType.java
@@ -1,6 +1,7 @@
package io.github.mivek.enums;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
/**
* @author mivek
@@ -17,10 +18,22 @@ public enum WeatherChangeType {
/** Probability change. */
PROB;
-
+ /**
+ * Returns the localized string using the JVM default locale.
+ * @return the translated string.
+ */
@Override
public String toString() {
- return Messages.getInstance().getString("WeatherChangeType." + name());
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns the localized string for the given locale.
+ * @param locale the locale to use.
+ * @return the translated string.
+ */
+ public String toString(final Locale locale) {
+ return Messages.getInstance().getString(locale, "WeatherChangeType." + name());
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherCode.java b/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherCode.java
index aa1b3ce5..149c59e3 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherCode.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherCode.java
@@ -3,12 +3,13 @@
import io.github.mivek.enums.Flag;
import io.github.mivek.enums.ReportType;
import io.github.mivek.internationalization.Messages;
+import java.time.LocalTime;
import java.util.EnumSet;
+import java.util.Locale;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.builder.ToStringBuilder;
-import java.time.LocalTime;
-
/**
* @author mivek
* Parent class of {@link Metar} and {@link TAF}.
@@ -165,17 +166,27 @@ public boolean isCorrected() {
}
/**
- * @return a description of the object.
+ * @return a description of the object using the JVM default locale.
*/
@Override
public String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns a locale-aware string representation.
+ * @param locale the locale to use for labels and sub-objects.
+ * @return the string representation.
+ */
+ public String toString(final Locale locale) {
return new ToStringBuilder(this).
- append(Messages.getInstance().getString("ToString.day.month"), day).
- append(Messages.getInstance().getString("ToString.report.time"), time).
- append(Messages.getInstance().getString("ToString.airport"), airport).
- appendSuper(super.toString()).
- append(Messages.getInstance().getString("ToString.message"), message).
- append(Messages.getInstance().getString("ToString.flags"), flags).
+ append(Messages.getInstance().getString(locale, "ToString.day.month"), day).
+ append(Messages.getInstance().getString(locale, "ToString.report.time"), time).
+ append(Messages.getInstance().getString(locale, "ToString.airport"), airport).
+ appendSuper(super.toString(locale)).
+ append(Messages.getInstance().getString(locale, "ToString.message"), message).
+ append(Messages.getInstance().getString(locale, "ToString.flags"),
+ flags.stream().map(f -> f.toString(locale)).collect(Collectors.joining(", ", "[", "]"))).
toString();
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherContainer.java b/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherContainer.java
index 6077d7e6..5eaafd29 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherContainer.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherContainer.java
@@ -2,10 +2,11 @@
import io.github.mivek.enums.LengthUnit;
import io.github.mivek.internationalization.Messages;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* @author mivek
@@ -196,28 +197,39 @@ public void setNsw(final boolean nsw) {
}
/**
- * @return string describing the object.
+ * @return string describing the object using the JVM default locale.
*/
@Override
public String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns a locale-aware string representation.
+ * @param locale the locale to use for labels and sub-objects.
+ * @return the string representation.
+ */
+ public String toString(final Locale locale) {
ToStringBuilder builder = new ToStringBuilder(this);
if (wind != null) {
- builder.appendToString(wind.toString());
+ builder.appendToString(wind.toString(locale));
}
if (visibility != null) {
- builder.appendToString(visibility.toString());
+ builder.appendToString(visibility.toString(locale));
}
if (verticalVisibility != null) {
- builder.append(Messages.getInstance().getString("ToString.vertical.visibility"), verticalVisibility);
- builder.append(Messages.getInstance().getString("ToString.vertical.visibility.unit"), verticalVisibilityUnit);
+ builder.append(Messages.getInstance().getString(locale, "ToString.vertical.visibility"), verticalVisibility);
+ builder.append(Messages.getInstance().getString(locale, "ToString.vertical.visibility.unit"), verticalVisibilityUnit);
}
- builder.append(Messages.getInstance().getString("ToString.clouds"), clouds.toString()).
- append(Messages.getInstance().getString("ToString.weather.conditions"), weatherConditions.toString());
+ builder.append(Messages.getInstance().getString(locale, "ToString.clouds"),
+ clouds.stream().map(c -> c.toString(locale)).collect(Collectors.joining(", ", "[", "]"))).
+ append(Messages.getInstance().getString(locale, "ToString.weather.conditions"),
+ weatherConditions.stream().map(w -> w.toString(locale)).collect(Collectors.joining(", ", "[", "]")));
if (windShear != null) {
- builder.appendToString(windShear.toString());
+ builder.appendToString(windShear.toString(locale));
}
- builder.append(Messages.getInstance().getString("ToString.cavok"), cavok).
- append(Messages.getInstance().getString("ToString.remark"), remark);
+ builder.append(Messages.getInstance().getString(locale, "ToString.cavok"), cavok).
+ append(Messages.getInstance().getString(locale, "ToString.remark"), remark);
return builder.toString();
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherLayer.java b/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherLayer.java
index 26ad4bb7..1f7e40c1 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherLayer.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/model/AbstractWeatherLayer.java
@@ -2,6 +2,7 @@
import io.github.mivek.enums.LengthUnit;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
@@ -75,21 +76,41 @@ public final void setUnit(final LengthUnit unit) {
}
/**
- * Appends intensity-specific information to the toString builder.
+ * Appends intensity-specific information to the toString builder using the default locale.
* Implemented by subclasses to add their intensity field.
*
* @param builder the ToStringBuilder to append to.
*/
protected abstract void appendIntensity(final ToStringBuilder builder);
+ /**
+ * Appends intensity-specific information to the toString builder for a given locale.
+ * The default implementation delegates to {@link #appendIntensity(ToStringBuilder)}.
+ *
+ * @param builder the ToStringBuilder to append to.
+ * @param locale the locale to use.
+ */
+ protected void appendIntensity(final ToStringBuilder builder, final Locale locale) {
+ appendIntensity(builder);
+ }
+
@Override
public final String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns a locale-aware string representation.
+ * @param locale the locale to use for labels and sub-objects.
+ * @return the string representation.
+ */
+ public String toString(final Locale locale) {
ToStringBuilder builder = new ToStringBuilder(this);
- appendIntensity(builder);
+ appendIntensity(builder, locale);
return builder.
- append(Messages.getInstance().getString("ToString.baseHeight"), baseHeight).
- append(Messages.getInstance().getString("ToString.depth"), depth).
- append(Messages.getInstance().getString("ToString.height.unit"), unit).
+ append(Messages.getInstance().getString(locale, "ToString.baseHeight"), baseHeight).
+ append(Messages.getInstance().getString(locale, "ToString.depth"), depth).
+ append(Messages.getInstance().getString(locale, "ToString.height.unit"), unit).
toString();
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/model/Cloud.java b/metarParser-entities/src/main/java/io/github/mivek/model/Cloud.java
index 9c8e7cec..88dc2211 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/model/Cloud.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/model/Cloud.java
@@ -4,6 +4,7 @@
import io.github.mivek.enums.CloudType;
import io.github.mivek.enums.LengthUnit;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
@@ -96,11 +97,33 @@ public void setType(final CloudType type) {
@Override
public final String toString() {
+ return toString(Locale.getDefault());
+ }
+
+ /**
+ * Returns a locale-aware string representation.
+ * @param locale the locale to use for labels and sub-objects.
+ * @return the string representation.
+ */
+ public String toString(final Locale locale) {
return new ToStringBuilder(this).
- append(Messages.getInstance().getString("ToString.quantity"), quantity).
- append(Messages.getInstance().getString("ToString.type"), type).
- append(Messages.getInstance().getString("ToString.height.feet"), height).
- append(Messages.getInstance().getString("ToString.cloud.unit"), unit).
+ append(Messages.getInstance().getString(locale, "ToString.quantity"), localized(quantity, locale)).
+ append(Messages.getInstance().getString(locale, "ToString.type"), localized(type, locale)).
+ append(Messages.getInstance().getString(locale, "ToString.height.feet"), height).
+ append(Messages.getInstance().getString(locale, "ToString.cloud.unit"), unit).
toString();
}
+
+ private static String localized(final Object obj, final Locale locale) {
+ if (obj == null) {
+ return null;
+ }
+ if (obj instanceof CloudQuantity q) {
+ return q.toString(locale);
+ }
+ if (obj instanceof CloudType t) {
+ return t.toString(locale);
+ }
+ return obj.toString();
+ }
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/model/Icing.java b/metarParser-entities/src/main/java/io/github/mivek/model/Icing.java
index 5c9f6711..bd154901 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/model/Icing.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/model/Icing.java
@@ -2,6 +2,7 @@
import io.github.mivek.enums.IcingIntensity;
import io.github.mivek.internationalization.Messages;
+import java.util.Locale;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
@@ -33,6 +34,12 @@ public void setIntensity(final IcingIntensity intensity) {
@Override
protected void appendIntensity(final ToStringBuilder builder) {
- builder.append(Messages.getInstance().getString("ToString.intensity"), intensity);
+ appendIntensity(builder, Locale.getDefault());
+ }
+
+ @Override
+ protected void appendIntensity(final ToStringBuilder builder, final Locale locale) {
+ builder.append(Messages.getInstance().getString(locale, "ToString.intensity"),
+ intensity != null ? intensity.toString(locale) : null);
}
}
diff --git a/metarParser-entities/src/main/java/io/github/mivek/model/Metar.java b/metarParser-entities/src/main/java/io/github/mivek/model/Metar.java
index 6c72cdc3..0d7326f2 100644
--- a/metarParser-entities/src/main/java/io/github/mivek/model/Metar.java
+++ b/metarParser-entities/src/main/java/io/github/mivek/model/Metar.java
@@ -2,11 +2,12 @@
import io.github.mivek.internationalization.Messages;
import io.github.mivek.model.trend.MetarTrend;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* Metar class.
@@ -126,15 +127,26 @@ public List