1 /*
2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 import java.util.Arrays;
24 import java.util.Locale;
25 import java.util.Objects;
26 import java.util.ResourceBundle;
27 import java.util.logging.Handler;
28 import java.util.logging.Level;
29 import java.util.logging.LogRecord;
30 import java.util.logging.Logger;
31 import resources.ListBundle;
32 
33 /**
34  * @test
35  * @bug 8013839
36  * @summary tests Logger.logrb(..., ResourceBundle);
37  * @build TestLogrbResourceBundle resources.ListBundle resources.ListBundle_fr
38  * @run main TestLogrbResourceBundle
39  * @author danielfuchs
40  */
41 public class TestLogrbResourceBundle {
42 
43     static final String LIST_BUNDLE_NAME = "resources.ListBundle";
44     static final String PROPERTY_BUNDLE_NAME = "resources.PropertyBundle";
45 
46     /**
47      * A dummy handler class that we can use to check the bundle/bundle name
48      * that was present in the last LogRecord instance published.
49      */
50     static final class TestHandler extends Handler {
51         ResourceBundle lastBundle = null;
52         String lastBundleName = null;
53         Object[] lastParams = null;
54         Throwable lastThrown = null;
55         String lastMessage = null;
56         @Override
publish(LogRecord record)57         public void publish(LogRecord record) {
58             lastBundle = record.getResourceBundle();
59             lastBundleName = record.getResourceBundleName();
60             lastParams = record.getParameters();
61             lastThrown = record.getThrown();
62             lastMessage = record.getMessage();
63         }
64 
65         @Override
flush()66         public void flush() {
67         }
68 
69         @Override
close()70         public void close() throws SecurityException {
71         }
72     }
73 
74     /**
75      * We're going to do the same test with each of the different new logrb
76      * forms.
77      * <ul>
78      *    <li> LOGRB_NO_ARGS: calling logrb with no message argument.
79      *    <li> LOGRB_SINGLE_ARG: calling logrb with a single message argument.
80      *    <li> LOGRB_ARG_ARRAY: calling logrb with an array of message arguments.
81      *    <li> LOGRB_VARARGS: calling logrb with a variable list of message arguments.
82      *    <li> LOGRB_THROWABLE: calling logrb with an exception.
83      * </ul>
84      */
85     private static enum TestCase {
86         LOGRB_NO_ARGS, LOGRB_SINGLE_ARG, LOGRB_ARG_ARRAY, LOGRB_VARARGS, LOGRB_THROWABLE;
87 
logrb(Logger logger, ResourceBundle bundle)88         public void logrb(Logger logger, ResourceBundle bundle) {
89             switch(this) {
90                 case LOGRB_NO_ARGS:
91                     logger.logrb(Level.CONFIG,
92                             TestLogrbResourceBundle.class.getName(),
93                             "main", bundle, "dummy");
94                     break;
95                 case LOGRB_SINGLE_ARG:
96                     logger.logrb(Level.CONFIG,
97                             TestLogrbResourceBundle.class.getName(),
98                             "main", bundle, "dummy", "bar");
99                     break;
100                 case LOGRB_ARG_ARRAY:
101                     logger.logrb(Level.CONFIG,
102                             TestLogrbResourceBundle.class.getName(),
103                             "main", bundle, "dummy",
104                             new Object[] { "bar", "baz"} );
105                     break;
106                 case LOGRB_VARARGS:
107                     logger.logrb(Level.CONFIG,
108                             TestLogrbResourceBundle.class.getName(),
109                             "main", bundle, "dummy",
110                             "bar", "baz" );
111                     break;
112                 case LOGRB_THROWABLE:
113                     logger.logrb(Level.CONFIG,
114                             TestLogrbResourceBundle.class.getName(),
115                             "main", bundle, "dummy",
116                             new Exception("dummy exception") );
117                     break;
118                 default:
119             }
120         }
121 
122         /**
123          * Checks that the last published logged record had the expected data.
124          * @param handler the TestHandler through which the record was published.
125          */
checkLogged(TestHandler handler)126         public void checkLogged(TestHandler handler) {
127             checkLogged(handler.lastMessage, handler.lastParams, handler.lastThrown);
128         }
129 
checkLogged(String message, Object[] parameters, Throwable thrown)130         private void checkLogged(String message, Object[] parameters, Throwable thrown) {
131             switch(this) {
132                 case LOGRB_NO_ARGS:
133                     if ("dummy".equals(message) && thrown == null
134                             && (parameters == null || parameters.length == 0)) {
135                         return; // OK: all was as expected.
136                     }
137                     break;
138                 case LOGRB_SINGLE_ARG:
139                     if ("dummy".equals(message) && thrown == null
140                             && parameters != null
141                             && parameters.length == 1
142                             && "bar".equals(parameters[0])) {
143                         return; // OK: all was as expected.
144                     }
145                     break;
146                 case LOGRB_VARARGS:
147                 case LOGRB_ARG_ARRAY:
148                     if ("dummy".equals(message) && thrown == null
149                             && parameters != null
150                             && parameters.length > 1
151                             && Arrays.deepEquals(new Object[] { "bar", "baz"},
152                                     parameters)) {
153                         return; // OK: all was as expected.
154                     }
155                     break;
156                 case LOGRB_THROWABLE:
157                     if ("dummy".equals(message) && thrown != null
158                             && thrown.getClass() == Exception.class
159                             && "dummy exception".equals(thrown.getMessage())) {
160                         return; // OK: all was as expected.
161                     }
162                     break;
163                 default:
164             }
165 
166             // We had some unexpected stuff: throw exception.
167             throw new RuntimeException(this + ": "
168                     + "Unexpected content in last published log record: "
169                     + "\n\tmessage=\"" + message + "\""
170                     + "\n\tparameters=" + Arrays.toString(parameters)
171                     + "\n\tthrown=" + thrown);
172         }
173     }
174 
getBaseName(ResourceBundle bundle)175     static String getBaseName(ResourceBundle bundle) {
176         return bundle == null ? null : bundle.getBaseBundleName();
177     }
178 
main(String... args)179     public static void main(String... args) throws Exception {
180 
181         Locale defaultLocale = Locale.getDefault();
182 
183         final ResourceBundle bundle = ResourceBundle.getBundle(LIST_BUNDLE_NAME);
184         final ResourceBundle bundle_fr =
185                     ResourceBundle.getBundle(LIST_BUNDLE_NAME, Locale.FRENCH);
186         final ResourceBundle propertyBundle = ResourceBundle.getBundle(PROPERTY_BUNDLE_NAME);
187         final ResourceBundle propertyBundle_fr =
188                     ResourceBundle.getBundle(PROPERTY_BUNDLE_NAME, Locale.FRENCH);
189         Logger foobar = Logger.getLogger("foo.bar");
190         final TestHandler handler = new TestHandler();
191         foobar.addHandler(handler);
192         foobar.setLevel(Level.CONFIG);
193 
194         final ResourceBundle anonBundle = new ListBundle();
195         try {
196             // First we're going to call logrb on a logger that
197             // has no bundle set...
198 
199             // For each possible logrb form...
200             for (TestCase test : TestCase.values()) {
201                 // For various resource bundles
202                 for (ResourceBundle b : new ResourceBundle[] {
203                     anonBundle, bundle, bundle_fr, propertyBundle,
204                     anonBundle, null, propertyBundle_fr,
205                 }) {
206                     // Prints the resource bundle base name (can be null,
207                     //   we don't enforce non-null names in logrb.
208                     final String baseName = getBaseName(b);
209                     System.out.println("Testing " + test + " with " + baseName);
210 
211                     // log in the 'foobar' logger using bundle 'b'
212                     test.logrb(foobar, b);
213 
214                     // check that the correct bundle was set in the published
215                     // LogRecord
216                     if (handler.lastBundle != b) {
217                         throw new RuntimeException("Unexpected bundle: "
218                                 + handler.lastBundle);
219                     }
220 
221                     // check that the correct bundle name was set in the published
222                     // LogRecord
223                     if (!Objects.equals(handler.lastBundleName, baseName)) {
224                         throw new RuntimeException("Unexpected bundle name: "
225                                 + handler.lastBundleName);
226                     }
227 
228                     // check that calling foobar.logrb() had no side effect on
229                     // the bundle used by foobar. foobar should still have no
230                     // bundle set.
231                     if (foobar.getResourceBundle() != null) {
232                         throw new RuntimeException("Unexpected bundle: "
233                             + foobar.getResourceBundle());
234                     }
235                     if (foobar.getResourceBundleName() != null) {
236                         throw new RuntimeException("Unexpected bundle: "
237                             + foobar.getResourceBundleName());
238                     }
239 
240                     // Test that the last published log record had all the
241                     // data that this test case had logged (message, parameters,
242                     // thrown...
243                     test.checkLogged(handler);
244                 }
245             }
246 
247             // No we're going to set a resource bundle on the foobar logger
248             // and do it all again...
249 
250             // For the same bundle in two different locales
251             for (ResourceBundle propBundle : new ResourceBundle[] {
252                 propertyBundle, propertyBundle_fr,
253             }) {
254 
255                 // set the bundle on foobar...
256                 foobar.setResourceBundle(propBundle);
257 
258                 // check the bundle was correctly set...
259                 if (!propBundle.equals(foobar.getResourceBundle())) {
260                     throw new RuntimeException("Unexpected bundle: "
261                             + foobar.getResourceBundle());
262                 }
263                 if (!Objects.equals(getBaseName(propBundle), foobar.getResourceBundleName())) {
264                     throw new RuntimeException("Unexpected bundle name: "
265                             + foobar.getResourceBundleName());
266                 }
267 
268                 System.out.println("Configuring " + foobar.getName() + " with "
269                         + propBundle);
270 
271                 // for each possible logrb form...
272                 for (TestCase test : TestCase.values()) {
273 
274                     // for various resource bundles
275                     for (ResourceBundle b : new ResourceBundle[] {
276                         anonBundle, bundle, null, bundle_fr, propertyBundle,
277                         anonBundle, propertyBundle_fr,
278                     }) {
279 
280                         final String baseName = getBaseName(b);
281                         System.out.println("Testing " + test + " with " + baseName);
282 
283                         // call foobar.logrb
284                         test.logrb(foobar, b);
285 
286                         // check which resource bundle was used (should be
287                         // the one passed to logrb)
288                         if (handler.lastBundle != b) {
289                             throw new RuntimeException("Unexpected bundle: "
290                                     + handler.lastBundle);
291                         }
292                         if (!Objects.equals(handler.lastBundleName, baseName)) {
293                             throw new RuntimeException("Unexpected bundle name: "
294                                     + handler.lastBundleName);
295                         }
296 
297                         // Verify there was no side effect on the bundle that
298                         // had been previously set on the logger...
299                         if (foobar.getResourceBundle() != propBundle) {
300                             throw new RuntimeException("Unexpected bundle: "
301                                 + foobar.getResourceBundle());
302                         }
303                         if (!Objects.equals(getBaseName(propBundle),
304                                 foobar.getResourceBundleName())) {
305                             throw new RuntimeException("Unexpected bundle name: "
306                                 + foobar.getResourceBundleName());
307                         }
308 
309                         // Checked that the published LogRecord had the
310                         // expected content logged by this test case.
311                         test.checkLogged(handler);
312                     }
313                 }
314             }
315 
316             // Now we're going to the same thing, but with a logger which
317             // has an inherited resource bundle.
318             Logger foobaz = Logger.getLogger("foo.bar.baz");
319 
320             // check that foobaz has no bundle set locally.
321             if (foobaz.getResourceBundle() != null) {
322                 throw new RuntimeException("Unexpected bundle: "
323                         + foobaz.getResourceBundle());
324             }
325             if (foobaz.getResourceBundleName() != null) {
326                 throw new RuntimeException("Unexpected bundle: "
327                         + foobaz.getResourceBundle());
328             }
329 
330             // The current locale should have no effect on logrb.
331             Locale.setDefault(Locale.GERMAN); // shouldn't change anything...
332 
333             // for each possible logrb form
334             for (TestCase test : TestCase.values()) {
335 
336                 // for various resource bundle
337                 for (ResourceBundle b : new ResourceBundle[] {
338                     anonBundle, bundle, bundle_fr, propertyBundle, null,
339                      anonBundle, propertyBundle_fr,
340                 }) {
341                     final String baseName = getBaseName(b);
342                     System.out.println("Testing " + test + " with "
343                             + foobaz.getName() + " and "
344                             + baseName);
345 
346                     // call foobaz.logrb with the bundle
347                     test.logrb(foobaz, b);
348 
349                     // check that the bundle passed to logrb was used.
350                     if (handler.lastBundle != b) {
351                         throw new RuntimeException("Unexpected bundle: "
352                                 + handler.lastBundle);
353                     }
354                     if (!Objects.equals(handler.lastBundleName, baseName)) {
355                         throw new RuntimeException("Unexpected bundle name: "
356                                 + handler.lastBundleName);
357                     }
358 
359                     // check that there was no effect on the bundle set
360                     // on foobaz: it should still be null.
361                     if (foobaz.getResourceBundle() != null) {
362                         throw new RuntimeException("Unexpected bundle: "
363                             + foobaz.getResourceBundle());
364                     }
365                     if (foobaz.getResourceBundleName() != null) {
366                         throw new RuntimeException("Unexpected bundle: "
367                             + foobaz.getResourceBundleName());
368                     }
369 
370                     // check that the last published log record had all the
371                     // data that was logged by this testcase.
372                     test.checkLogged(handler);
373                 }
374             }
375 
376         } finally {
377             Locale.setDefault(defaultLocale);
378         }
379 
380     }
381 }
382