OrekitMessages.java

  1. /* Copyright 2002-2013 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.errors;

  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.io.InputStreamReader;
  21. import java.net.URL;
  22. import java.net.URLConnection;
  23. import java.util.Locale;
  24. import java.util.MissingResourceException;
  25. import java.util.PropertyResourceBundle;
  26. import java.util.ResourceBundle;

  27. import org.apache.commons.math3.exception.util.Localizable;

  28. /**
  29.  * Enumeration for localized messages formats.
  30.  * <p>
  31.  * The constants in this enumeration represent the available
  32.  * formats as localized strings. These formats are intended to be
  33.  * localized using simple properties files, using the constant
  34.  * name as the key and the property value as the message format.
  35.  * The source English format is provided in the constants themselves
  36.  * to serve both as a reminder for developers to understand the parameters
  37.  * needed by each format, as a basis for translators to create
  38.  * localized properties files, and as a default format if some
  39.  * translation is missing.
  40.  * </p>
  41.  * @since 2.1
  42.  */
  43. public enum OrekitMessages implements Localizable {

  44.     // CHECKSTYLE: stop JavadocVariable check

  45.     INTERNAL_ERROR("internal error, contact maintenance at {0}"),
  46.     ALTITUDE_BELOW_ALLOWED_THRESHOLD("altitude ({0} m) is below the {1} m allowed threshold"),
  47.     TRAJECTORY_INSIDE_BRILLOUIN_SPHERE("trajectory inside the Brillouin sphere (r = {0})"),
  48.     ALMOST_EQUATORIAL_ORBIT("almost equatorial orbit (i = {0} degrees)"),
  49.     ALMOST_CRITICALLY_INCLINED_ORBIT("almost critically inclined orbit (i = {0} degrees)"),
  50.     UNABLE_TO_COMPUTE_ECKSTEIN_HECHLER_MEAN_PARAMETERS("unable to compute Eckstein-Hechler mean parameters after {0} iterations"),
  51.     NULL_PARENT_FOR_FRAME("null parent for frame {0}"),
  52.     FRAME_ALREADY_ATTACHED("frame {0} is already attached to frame {1}"),
  53.     FRAME_NOT_ATTACHED("frame {0} is not attached to the main frames tree"),
  54.     FRAME_ANCESTOR_OF_BOTH_FRAMES("frame {0} is an ancestor of both frames {1} and {2}"),
  55.     FRAME_ANCESTOR_OF_NEITHER_FRAME("frame {0} is an ancestor of neither frame {1} nor {2}"),
  56.     FRAME_NO_NTH_ANCESTOR("frame {0} has depth {1}, it cannot have an ancestor {2} levels above"),
  57.     UNSUPPORTED_LOCAL_ORBITAL_FRAME("unsupported local orbital frame, supported types: {0} and {1}"),
  58.     NON_PSEUDO_INERTIAL_FRAME_NOT_SUITABLE_FOR_DEFINING_ORBITS("non pseudo-inertial frame \"{0}\" is not suitable for defining orbits"),
  59.     DATA_ROOT_DIRECTORY_DOES_NOT_EXIST("data root directory {0} does not exist"),
  60.     NOT_A_DIRECTORY("{0} is not a directory"),
  61.     NEITHER_DIRECTORY_NOR_ZIP_OR_JAR("{0} is neither a directory nor a zip/jar archive file"),
  62.     UNABLE_TO_FIND_RESOURCE("unable to find resource {0} in classpath"),
  63.     NO_EARTH_ORIENTATION_PARAMETERS_LOADED("no Earth Orientation Parameters loaded"),
  64.     MISSING_EARTH_ORIENTATION_PARAMETERS_BETWEEN_DATES("missing Earth Orientation Parameters between {0} and {1}"),
  65.     NOT_A_SUPPORTED_IERS_DATA_FILE("file {0} is not a supported IERS data file"),
  66.     INCONSISTENT_DATES_IN_IERS_FILE("inconsistent dates in IERS file {0}: {1}-{2}-{3} and MJD {4}"),
  67.     UNEXPECTED_DATA_AFTER_LINE_IN_FILE("unexpected data after line {0} in file {1}: {2}"),
  68.     NON_CHRONOLOGICAL_DATES_IN_FILE("non-chronological dates in file {0}, line {1}"),
  69.     NO_IERS_UTC_TAI_HISTORY_DATA_LOADED("no IERS UTC-TAI history data loaded"),
  70.     NO_ENTRIES_IN_IERS_UTC_TAI_HISTORY_FILE("no entries found in IERS UTC-TAI history file {0}"),
  71.     MISSING_SERIE_J_IN_FILE("missing serie j = {0} in file {1} (line {2})"),
  72.     CANNOT_PARSE_BOTH_TAU_AND_GAMMA("cannot parse both \u03c4 and \u03b3 from the same Poissons series file"),
  73.     UNEXPECTED_END_OF_FILE_AFTER_LINE("unexpected end of file {0} (after line {1})"),
  74.     UNABLE_TO_PARSE_LINE_IN_FILE("unable to parse line {0} of file {1}:\n{2}"),
  75.     UNABLE_TO_FIND_FILE("unable to find file {0}"),
  76.     SPACECRAFT_MASS_BECOMES_NEGATIVE("spacecraft mass becomes negative: {0} kg"),
  77.     POSITIVE_FLOW_RATE("positive flow rate (q: {0})"),
  78.     NO_GRAVITY_FIELD_DATA_LOADED("no gravity field data loaded"),
  79.     GRAVITY_FIELD_NORMALIZATION_UNDERFLOW("gravity field normalization underflow for degree {0} and order {1}"),
  80.     NO_OCEAN_TIDE_DATA_LOADED("no ocean tide data loaded"),
  81.     OCEAN_TIDE_DATA_DEGREE_ORDER_LIMITS("ocean tide data file {0} limited to degree {1} and order {2}"),
  82.     OCEAN_TIDE_LOAD_DEFORMATION_LIMITS("load deformation coefficients limited to degree {0}, cannot parse degree {1} term from file {2}"),
  83.     POLAR_TRAJECTORY("polar trajectory (distance to polar axis: {0})"),
  84.     UNEXPECTED_FILE_FORMAT_ERROR_FOR_LOADER("unexpected format error for file {0} with loader {1}"),
  85.     DUPLICATED_GRAVITY_FIELD_COEFFICIENT_IN_FILE("duplicated gravity field coefficient {0}({1}, {2}) in file {3}"),
  86.     MISSING_GRAVITY_FIELD_COEFFICIENT_IN_FILE("missing gravity field coefficient {0}({1}, {2}) in file {3}"),
  87.     TOO_LARGE_DEGREE_FOR_GRAVITY_FIELD("too large degree (n = {0}, potential maximal degree is {1})"),
  88.     TOO_LARGE_ORDER_FOR_GRAVITY_FIELD("too large order (m = {0}, potential maximal order is {1})"),
  89.     SEVERAL_REFERENCE_DATES_IN_GRAVITY_FIELD("several reference dates ({0} and {1}) found in gravity field file {2}"),
  90.     NO_TLE_FOR_OBJECT("no TLE data available for object {0}"),
  91.     NO_TLE_FOR_LAUNCH_YEAR_NUMBER_PIECE("no TLE data available for launch year {0}, launch number {1}, launch piece {2}"),
  92.     NOT_TLE_LINES("lines {0} and {1} are not TLE lines:\n{0}: \"{2}\"\n{1}: \"{3}\""),
  93.     MISSING_SECOND_TLE_LINE("expected a second TLE line after line {0}:\n{0}: \"{1}\""),
  94.     TLE_LINES_DO_NOT_REFER_TO_SAME_OBJECT("TLE lines do not refer to the same object:\n{0}\n{1}"),
  95.     TLE_CHECKSUM_ERROR("wrong checksum of TLE line {0}, expected {1} but got {2} ({3})"),
  96.     NO_TLE_DATA_AVAILABLE("no TLE data available"),
  97.     NOT_POSITIVE_SPACECRAFT_MASS("spacecraft mass is not positive: {0} kg"),
  98.     TOO_LARGE_ECCENTRICITY_FOR_PROPAGATION_MODEL("too large eccentricity for propagation model: e = {0}"),
  99.     NO_SOLAR_ACTIVITY_AT_DATE("no solar activity available at {0}, data available only in range [{1}, {2}]"),
  100.     NON_EXISTENT_MONTH("non-existent month {0}"),
  101.     NON_EXISTENT_YEAR_MONTH_DAY("non-existent date {0}-{1}-{2}"),
  102.     NON_EXISTENT_WEEK_DATE("non-existent week date {0}-W{1}-{2}"),
  103.     NON_EXISTENT_DATE("non-existent date {0}"),
  104.     NON_EXISTENT_DAY_NUMBER_IN_YEAR("no day number {0} in year {1}"),
  105.     NON_EXISTENT_HMS_TIME("non-existent time {0}:{1}:{2}"),
  106.     NON_EXISTENT_TIME("non-existent time {0}"),
  107.     OUT_OF_RANGE_SECONDS_NUMBER("out of range seconds number: {0}"),
  108.     ANGLE_TYPE_NOT_SUPPORTED("angle type not supported, supported angles: {0}, {1} and {2}"),
  109.     SATELLITE_COLLIDED_WITH_TARGET("satellite collided with target"),
  110.     ATTITUDE_POINTING_LAW_DOES_NOT_POINT_TO_GROUND("attitude pointing law misses ground"),
  111.     ORBIT_AND_ATTITUDE_DATES_MISMATCH("orbit date ({0}) does not match attitude date ({1})"),
  112.     FRAMES_MISMATCH("frame {0} does not match frame {1}"),
  113.     INITIAL_STATE_NOT_SPECIFIED_FOR_ORBIT_PROPAGATION("initial state not specified for orbit propagation"),
  114.     PROPAGATOR_NOT_IN_EPHEMERIS_GENERATION_MODE("propagator is not in ephemeris generation mode"),
  115.     EVENT_DATE_TOO_CLOSE("event date {0}, greater than {1} minus {3} seconds and smaller than {2} plus {3} seconds, cannot be added"),
  116.     UNABLE_TO_READ_JPL_HEADER("unable to read header record from JPL ephemerides binary file {0}"),
  117.     INCONSISTENT_ASTRONOMICAL_UNIT_IN_FILES("inconsistent values of astronomical unit in JPL ephemerides files: ({0} and {1})"),
  118.     INCONSISTENT_EARTH_MOON_RATIO_IN_FILES("inconsistent values of Earth/Moon mass ratio in JPL ephemerides files: ({0} and {1})"),
  119.     NO_DATA_LOADED_FOR_CELESTIAL_BODY("no data loaded for celestial body {0}"),
  120.     NOT_A_JPL_EPHEMERIDES_BINARY_FILE("file {0} is not a JPL ephemerides binary file"),
  121.     NOT_A_MARSHALL_SOLAR_ACTIVITY_FUTURE_ESTIMATION_FILE("file {0} is not a Marshall Solar Activity Future Estimation (MSAFE) file"),
  122.     NO_JPL_EPHEMERIDES_BINARY_FILES_FOUND("no JPL ephemerides binary files found"),
  123.     OUT_OF_RANGE_BODY_EPHEMERIDES_DATE("out of range date for {0} ephemerides: {1}"),
  124.     OUT_OF_RANGE_EPHEMERIDES_DATE("out of range date for ephemerides: {0}, [{1}, {2}]"),
  125.     UNEXPECTED_TWO_ELEVATION_VALUES_FOR_ONE_AZIMUTH("unexpected two elevation values: {0} and {1}, for one azimuth: {2}"),
  126.     UNSUPPORTED_PARAMETER_NAME("unsupported parameter name {0}, supported names: {1}"),
  127.     UNKNOWN_ADDITIONAL_STATE("unknown additional state \"{0}\""),
  128.     UNKNOWN_MONTH("unknown month \"{0}\""),
  129.     SINGULAR_JACOBIAN_FOR_ORBIT_TYPE("Jacobian matrix for type {0} is singular with current orbit"),
  130.     STATE_JACOBIAN_NOT_INITIALIZED("state Jacobian has not been initialized yet"),
  131.     STATE_JACOBIAN_NEITHER_6X6_NOR_7X7("state Jacobian is a {0}x{1} matrix, it should be either a 6x6 or a 7x7 matrix"),
  132.     STATE_AND_PARAMETERS_JACOBIANS_ROWS_MISMATCH("state Jacobian has {0} rows but parameters Jacobian has {1} rows"),
  133.     STEPS_NOT_INITIALIZED_FOR_FINITE_DIFFERENCES("finite differences steps for force models derivatives not initialized"),
  134.     INITIAL_MATRIX_AND_PARAMETERS_NUMBER_MISMATCH("initial Jacobian matrix has {0} columns, but {1} parameters have been selected"),
  135.     ORBIT_A_E_MISMATCH_WITH_CONIC_TYPE("orbit should be either elliptic with a > 0 and e < 1 or hyperbolic with a < 0 and e > 1, a = {0}, e = {1}"),
  136.     ORBIT_ANOMALY_OUT_OF_HYPERBOLIC_RANGE("true anomaly {0} out of hyperbolic range (e = {1}, {2} < v < {3})"),
  137.     HYPERBOLIC_ORBIT_NOT_HANDLED_AS("hyperbolic orbits cannot be handled as {0} instances"),
  138.     CCSDS_DATE_INVALID_PREAMBLE_FIELD("invalid preamble field in CCSDS date: {0}"),
  139.     CCSDS_DATE_INVALID_LENGTH_TIME_FIELD("invalid time field length in CCSDS date: {0}, expected {1}"),
  140.     CCSDS_DATE_MISSING_AGENCY_EPOCH("missing agency epoch in CCSDS date"),
  141.     CCSDS_UNEXPECTED_KEYWORD("unexpected keyword in CCSDS line number {0} of file {1}:\n{2}"),
  142.     CCSDS_UNKNOWN_GM("the central body gravitational coefficient cannot be retrieved from the ODM"),
  143.     CCSDS_UNKNOWN_SPACECRAFT_MASS("there is no spacecraft mass associated with this ODM file"),
  144.     CCSDS_UNKNOWN_CONVENTIONS("no IERS conventions have been set before parsing"),
  145.     CCSDS_INVALID_FRAME("frame {0} is not valid in this ODM file context"),
  146.     CCSDS_OEM_INCONSISTENT_TIME_SYSTEMS("inconsistent time systems in the ephemeris blocks: {0} \u2260 {1}"),
  147.     ADDITIONAL_STATE_NAME_ALREADY_IN_USE("name \"{0}\" is already used for an additional state"),
  148.     NON_RESETABLE_STATE("reset state not allowed"),
  149.     DSST_NEWCOMB_OPERATORS_COMPUTATION("Cannot compute Newcomb operators for sigma > rho ({0} > {1})"),
  150.     DSST_VMNS_COEFFICIENT_ERROR_MS("Cannot compute the Vmns coefficient with m > n ({0} > {1})"),
  151.     DSST_SPR_SHADOW_INCONSISTENT("inconsistent shadow computation: entry = {0} whereas exit = {1}"),
  152.     DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD("The current orbit has an eccentricity ({0} > 0.5). DSST needs an unimplemented time dependent numerical method to compute the averaged rates"),
  153.     SP3_UNSUPPORTED_VERSION("unsupported sp3 file version {0}"),
  154.     SP3_UNSUPPORTED_TIMESYSTEM("unsupported time system {0}"),
  155.     SP3_UNEXPECTED_END_OF_FILE("unexpected end of sp3 file (after line {0})"),
  156.     NON_EXISTENT_GEOMAGNETIC_MODEL("non-existent geomagnetic model {0} for year {1}"),
  157.     UNSUPPORTED_TIME_TRANSFORM("geomagnetic model {0} with epoch {1} does not support time transformation, no secular variation coefficients defined"),
  158.     OUT_OF_RANGE_TIME_TRANSFORM("time transformation of geomagnetic model {0} with epoch {1} is outside its validity range: {2} != [{3}, {4}]"),
  159.     NOT_ENOUGH_CACHED_NEIGHBORS("too small number of cached neighbors: {0} (must be at least {1})"),
  160.     NO_CACHED_ENTRIES("no cached entries"),
  161.     NON_CHRONOLOGICALLY_SORTED_ENTRIES("generated entries not sorted: {0} > {1}"),
  162.     NO_DATA_GENERATED("no data generated around date: {0}"),
  163.     UNABLE_TO_GENERATE_NEW_DATA_BEFORE("unable to generate new data before {0}"),
  164.     UNABLE_TO_GENERATE_NEW_DATA_AFTER("unable to generate new data after {0}"),
  165.     DUPLICATED_ABSCISSA("abscissa {0} is duplicated"),
  166.     EMPTY_INTERPOLATION_SAMPLE("sample for interpolation is empty"),
  167.     UNABLE_TO_COMPUTE_HYPERBOLIC_ECCENTRIC_ANOMALY("unable to compute hyperbolic eccentric anomaly from the mean anomaly after {0} iterations");

  168.     // CHECKSTYLE: resume JavadocVariable check

  169.     /** Base name of the resource bundle in classpath. */
  170.     private static final String RESOURCE_BASE_NAME = "assets/org/orekit/localization/OrekitMessages";

  171.     /** Source English format. */
  172.     private final String sourceFormat;

  173.     /** Simple constructor.
  174.      * @param sourceFormat source English format to use when no
  175.      * localized version is available
  176.      */
  177.     private OrekitMessages(final String sourceFormat) {
  178.         this.sourceFormat = sourceFormat;
  179.     }

  180.     /** {@inheritDoc} */
  181.     public String getSourceString() {
  182.         return sourceFormat;
  183.     }

  184.     /** {@inheritDoc} */
  185.     public String getLocalizedString(final Locale locale) {
  186.         try {
  187.             final ResourceBundle bundle =
  188.                     ResourceBundle.getBundle(RESOURCE_BASE_NAME, locale, new UTF8Control());
  189.             if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) {
  190.                 final String translated = bundle.getString(name());
  191.                 if ((translated != null) &&
  192.                     (translated.length() > 0) &&
  193.                     (!translated.toLowerCase().contains("missing translation"))) {
  194.                     // the value of the resource is the translated format
  195.                     return translated;
  196.                 }
  197.             }

  198.         } catch (MissingResourceException mre) {
  199.             // do nothing here
  200.         }

  201.         // either the locale is not supported or the resource is not translated or
  202.         // it is unknown: don't translate and fall back to using the source format
  203.         return sourceFormat;

  204.     }

  205.     /** Control class loading properties in UTF-8 encoding.
  206.      * <p>
  207.      * This class has been very slightly adapted from BalusC answer to question: <a
  208.      * href="http://stackoverflow.com/questions/4659929/how-to-use-utf-8-in-resource-properties-with-resourcebundle">
  209.      * How to use UTF-8 in resource properties with ResourceBundle</a>.
  210.      * </p>
  211.      * @since 6.0
  212.      */
  213.     public static class UTF8Control extends ResourceBundle.Control {

  214.         /** {@inheritDoc} */
  215.         @Override
  216.         public ResourceBundle newBundle(final String baseName, final Locale locale, final String format,
  217.                                         final ClassLoader loader, final boolean reload)
  218.             throws IllegalAccessException, InstantiationException, IOException {
  219.             // The below is a copy of the default implementation.
  220.             final String bundleName = toBundleName(baseName, locale);
  221.             final String resourceName = toResourceName(bundleName, "utf8");
  222.             ResourceBundle bundle = null;
  223.             InputStream stream = null;
  224.             if (reload) {
  225.                 final URL url = loader.getResource(resourceName);
  226.                 if (url != null) {
  227.                     final URLConnection connection = url.openConnection();
  228.                     if (connection != null) {
  229.                         connection.setUseCaches(false);
  230.                         stream = connection.getInputStream();
  231.                     }
  232.                 }
  233.             } else {
  234.                 stream = loader.getResourceAsStream(resourceName);
  235.             }
  236.             if (stream != null) {
  237.                 try {
  238.                     // Only this line is changed to make it to read properties files as UTF-8.
  239.                     bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
  240.                 } finally {
  241.                     stream.close();
  242.                 }
  243.             }
  244.             return bundle;
  245.         }

  246.     }

  247. }