View Javadoc
1   /**
2    * This file is part of Indicators.
3    *
4    * Indicators is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * Indicators is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with Indicators. If not, see <https://www.gnu.org/licenses/>.
16   */
17  package fr.inrae.agroclim.indicators.resources;
18  
19  import java.text.MessageFormat;
20  import java.time.LocalDateTime;
21  import java.time.format.DateTimeFormatter;
22  import java.time.format.DateTimeParseException;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.MissingResourceException;
28  import java.util.Objects;
29  import java.util.ResourceBundle;
30  
31  import lombok.Getter;
32  
33  /**
34   * Resources from .properties file.
35   *
36   * Last change $Date$
37   *
38   * @author $Author$
39   * @version $Revision$
40   */
41  public final class Resources {
42  
43      /**
44       * The locale for the bundle.
45       */
46      private Locale currentLocale;
47  
48      /**
49       * Path of .property resource.
50       */
51      @Getter
52      private String bundleName;
53  
54      /**
55       * Resource bundle.
56       */
57      private ResourceBundle resourceBundle;
58  
59      /**
60       * Constructor.
61       *
62       * @param bundle resource bundle build outside.
63       */
64      public Resources(final ResourceBundle bundle) {
65          bundleName = bundle.getBaseBundleName();
66          currentLocale = bundle.getLocale();
67          resourceBundle = bundle;
68      }
69  
70      /**
71       * Constructor.
72       *
73       * @param name File of message resource.
74       * @param locale Locale for the bundle.
75       */
76      public Resources(final String name, final Locale locale) {
77          bundleName = name;
78          currentLocale = locale;
79          resourceBundle = ResourceBundle.getBundle(bundleName, currentLocale);
80          // Fallback to xxxx.properties and not xxxx_current_locale.properties.
81          if (!resourceBundle.getLocale().equals(locale)) {
82              resourceBundle = ResourceBundle.getBundle(bundleName, Locale.ROOT);
83          }
84      }
85  
86      /**
87       * Return message with inlined arguments.
88       *
89       * @param key message key
90       * @param messageArguments arguments for the message.
91       * @return message with arguments or exclamation message
92       */
93      public String format(final String key,
94              final Object... messageArguments) {
95          try {
96              final MessageFormat formatter = new MessageFormat(resourceBundle.getString(key), currentLocale);
97              return formatter.format(messageArguments);
98          } catch (final MissingResourceException e) {
99              if (messageArguments == null) {
100                 return '!' + key + '!';
101             }
102             return '!' + key + " : " + Arrays.toString(messageArguments) + "!";
103         }
104     }
105 
106     /**
107      * @return keys of resource
108      */
109     public List<String> getKeys() {
110         return Collections.list(resourceBundle.getKeys());
111     }
112 
113     /**
114      * Retrieve date from key.
115      *
116      * 2 patterns available : yyyyMMddHHmmss or
117      * DateTimeFormatter.ISO_LOCAL_DATE_TIME.
118      *
119      * @param key message key
120      * @return date time
121      * @throws DateTimeParseException if unable to parse the requested result
122      */
123     public LocalDateTime getLocalDateTime(final String key)
124             throws DateTimeParseException {
125         final String val = getString(key);
126         DateTimeFormatter formatter;
127         DateTimeParseException exception = null;
128         for (final String format : Arrays.asList("yyyyMMddHHmmss",
129                 "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd HH:mm:ss")) {
130             try {
131                 formatter = DateTimeFormatter.ofPattern(format);
132                 return formatter.parse(getString(key), LocalDateTime::from);
133             } catch (final DateTimeParseException ex) {
134                 exception = ex;
135             }
136         }
137         throw new DateTimeParseException(
138                 String.format(
139                         "Value of key \"%s\" could not be parsed: %s",
140                         key,
141                         val),
142                 val,
143                 0,
144                 exception);
145     }
146 
147     /**
148      * Retrieve message from key.
149      *
150      * @param key message key
151      * @return message value or exclamation message
152      */
153     public String getString(final String key) {
154         try {
155             return resourceBundle.getString(key);
156         } catch (final MissingResourceException e) {
157             return '!' + key + '!';
158         }
159     }
160 
161     /**
162      * Get build version and build date of library.
163      *
164      * @return version and date
165      */
166     public String getVersionAndBuildDate() {
167         final String version = getString("version");
168         final String date = getString("build.date")
169                 .replace("-", "")
170                 .replace(" ", "")
171                 .replace(":", "");
172         return version + "+" + date;
173     }
174 
175     /**
176      * Refresh bundle using current locale and current bundle.
177      */
178     private void refresh() {
179         resourceBundle = ResourceBundle.getBundle(bundleName, currentLocale);
180     }
181 
182     /**
183      * @param name File of message resource.
184      */
185     public void setBundleName(final String name) {
186         bundleName = name;
187         refresh();
188     }
189 
190     /**
191      * @param locale Locale for the bundle.
192      */
193     public void setLocale(final Locale locale) {
194         if (Objects.equals(currentLocale, locale)) {
195             return;
196         }
197         currentLocale = locale;
198         refresh();
199     }
200 }