View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  /*
21   * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
22   * All changes made to this file manually will be overwritten
23   * if this tool runs again. Better make changes in the template file.
24   */
25  
26  package org.apache.commons.compress.harmony.archive.internal.nls;
27  
28  import java.security.AccessController;
29  import java.security.PrivilegedAction;
30  import java.util.Arrays;
31  import java.util.Locale;
32  import java.util.MissingResourceException;
33  import java.util.Objects;
34  import java.util.ResourceBundle;
35  
36  //import org.apache.commons.compress.harmony.kernel.vm.VM;
37  
38  /**
39   * This class retrieves strings from a resource bundle and returns them, formatting them with MessageFormat when required.
40   * <p>
41   * It is used by the system classes to provide national language support, by looking up messages in the {@code
42   *    org.apache.commons.compress.harmony.archive.internal.nls.messages
43   * } resource bundle. Note that if this file is not available, or an invalid key is looked up, or resource bundle support is not available, the key itself
44   * will be returned as the associated message. This means that the <em>KEY</em> should a reasonable human-readable (english) string.
45   */
46  public class Messages {
47  
48      // ResourceBundle holding the system messages.
49      private static ResourceBundle bundle;
50  
51      static {
52          // Attempt to load the messages.
53          try {
54              bundle = setLocale(Locale.getDefault(), "org.apache.commons.compress.harmony.archive.internal.nls.messages"); //$NON-NLS-1$
55          } catch (final Throwable e) {
56              e.printStackTrace();
57          }
58      }
59  
60      /**
61       * Generates a formatted text string given a source string containing "argument markers" of the form "{argNum}" where each argNum must be in the range 0..9.
62       * The result is generated by inserting the toString of each argument into the position indicated in the string.
63       * <p>
64       * To insert the "{" character into the output, use a single backslash character to escape it (i.e. "\{"). The "}" character does not need to be escaped.
65       *
66       * @param format String the format to use when printing.
67       * @param args   Object[] the arguments to use.
68       * @return String the formatted message.
69       */
70      public static String format(final String format, final Object[] args) {
71          final StringBuilder answer = new StringBuilder(format.length() + args.length * 20);
72          final String[] argStrings = new String[args.length];
73          Arrays.setAll(argStrings, i -> Objects.toString(args[i], "<null>")); //$NON-NLS-1$
74          int lastI = 0;
75          for (int i = format.indexOf('{', 0); i >= 0; i = format.indexOf('{', lastI)) {
76              if (i != 0 && format.charAt(i - 1) == '\\') {
77                  // It's escaped, just print and loop.
78                  if (i != 1) {
79                      answer.append(format.substring(lastI, i - 1));
80                  }
81                  answer.append('{');
82                  lastI = i + 1;
83              } else // It's a format character.
84              if (i > format.length() - 3) {
85                  // Bad format, just print and loop.
86                  answer.append(format.substring(lastI));
87                  lastI = format.length();
88              } else {
89                  final int argnum = (byte) Character.digit(format.charAt(i + 1), 10);
90                  if (argnum < 0 || format.charAt(i + 2) != '}') {
91                      // Bad format, just print and loop.
92                      answer.append(format.substring(lastI, i + 1));
93                      lastI = i + 1;
94                  } else {
95                      // Got a good one!
96                      answer.append(format.substring(lastI, i));
97                      if (argnum >= argStrings.length) {
98                          answer.append("<missing argument>"); //$NON-NLS-1$
99                      } else {
100                         answer.append(argStrings[argnum]);
101                     }
102                     lastI = i + 3;
103                 }
104             }
105         }
106         if (lastI < format.length()) {
107             answer.append(format.substring(lastI));
108         }
109         return answer.toString();
110     }
111 
112     /**
113      * Gets a message which has no arguments.
114      *
115      * @param msg String the key to look up.
116      * @return String the message for that key in the system message bundle.
117      */
118     public static String getString(final String msg) {
119         if (bundle == null) {
120             return msg;
121         }
122         try {
123             return bundle.getString(msg);
124         } catch (final MissingResourceException e) {
125             return "Missing message: " + msg; //$NON-NLS-1$
126         }
127     }
128 
129     /**
130      * Gets a message which takes 1 character argument.
131      *
132      * @param msg String the key to look up.
133      * @param arg char the character to insert in the formatted output.
134      * @return String the message for that key in the system message bundle.
135      */
136     public static String getString(final String msg, final char arg) {
137         return getString(msg, new Object[] { String.valueOf(arg) });
138     }
139 
140     /**
141      * Gets a message which takes 1 integer argument.
142      *
143      * @param msg String the key to look up.
144      * @param arg int the integer to insert in the formatted output.
145      * @return String the message for that key in the system message bundle.
146      */
147     public static String getString(final String msg, final int arg) {
148         return getString(msg, new Object[] { Integer.toString(arg) });
149     }
150 
151     /**
152      * Gets a message which takes 1 argument.
153      *
154      * @param msg String the key to look up.
155      * @param arg Object the object to insert in the formatted output.
156      * @return String the message for that key in the system message bundle.
157      */
158     public static String getString(final String msg, final Object arg) {
159         return getString(msg, new Object[] { arg });
160     }
161 
162     /**
163      * Gets a message which takes 2 arguments.
164      *
165      * @param msg  String the key to look up.
166      * @param arg1 Object an object to insert in the formatted output.
167      * @param arg2 Object another object to insert in the formatted output.
168      * @return String the message for that key in the system message bundle.
169      */
170     public static String getString(final String msg, final Object arg1, final Object arg2) {
171         return getString(msg, new Object[] { arg1, arg2 });
172     }
173 
174     /**
175      * Gets a message which takes several arguments.
176      *
177      * @param msg  String the key to look up.
178      * @param args Object[] the objects to insert in the formatted output.
179      * @return String the message for that key in the system message bundle.
180      */
181     public static String getString(final String msg, final Object[] args) {
182         String format = msg;
183 
184         if (bundle != null) {
185             try {
186                 format = bundle.getString(msg);
187             } catch (final MissingResourceException ignored) {
188                 // ignored
189             }
190         }
191 
192         return format(format, args);
193     }
194 
195     /**
196      * Changes the locale of the messages.
197      *
198      * @param locale   Locale the locale to change to.
199      * @param resource resource name.
200      * @return The ResourceBundle.
201      */
202     public static ResourceBundle setLocale(final Locale locale, final String resource) {
203         try {
204             // VM.bootCallerClassLoader() returns null
205             final ClassLoader loader = null; // VM.bootCallerClassLoader();
206             return (ResourceBundle) AccessController.doPrivileged(
207                     (PrivilegedAction<Object>) () -> ResourceBundle.getBundle(resource, locale, loader != null ? loader : ClassLoader.getSystemClassLoader()));
208         } catch (final MissingResourceException ignored) {
209             // ignored
210         }
211         return null;
212     }
213 }