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.security.AccessControlException; 24 import java.security.Permission; 25 import java.security.Permissions; 26 import java.security.Policy; 27 import java.security.ProtectionDomain; 28 import java.util.Locale; 29 import java.util.Objects; 30 import java.util.PropertyPermission; 31 import java.util.ResourceBundle; 32 import java.util.logging.Handler; 33 import java.util.logging.Level; 34 import java.util.logging.LogManager; 35 import java.util.logging.LogRecord; 36 import java.util.logging.Logger; 37 import java.util.logging.LoggingPermission; 38 import resources.ListBundle; 39 40 /** 41 * @test 42 * @bug 8013839 43 * @summary tests Logger.setResourceBundle; 44 * @build TestSetResourceBundle resources.ListBundle resources.ListBundle_fr 45 * @run main/othervm TestSetResourceBundle UNSECURE 46 * @run main/othervm TestSetResourceBundle PERMISSION 47 * @run main/othervm TestSetResourceBundle SECURE 48 * @author danielfuchs 49 */ 50 public class TestSetResourceBundle { 51 52 final static String LIST_BUNDLE_NAME = "resources.ListBundle"; 53 final static String PROPERTY_BUNDLE_NAME = "resources.PropertyBundle"; 54 55 /** 56 * A dummy handler class that we can use to check the bundle/bundle name 57 * that was present in the last LogRecord instance published. 58 */ 59 static final class TestHandler extends Handler { 60 ResourceBundle lastBundle = null; 61 String lastBundleName = null; 62 @Override 63 public void publish(LogRecord record) { 64 lastBundle = record.getResourceBundle(); 65 lastBundleName = record.getResourceBundleName(); 66 } 67 68 @Override 69 public void flush() { 70 } 71 72 @Override 73 public void close() throws SecurityException { 74 } 75 } 76 77 /** 78 * We will test setResourceBundle() in 3 configurations. 79 * UNSECURE: No security manager. 80 * SECURE: With the security manager present - and the required 81 * LoggingPermission("control") granted. 82 * PERMISSION: With the security manager present - and the required 83 * LoggingPermission("control") *not* granted. Here we will 84 * test that the expected security permission is thrown. 85 */ 86 public static enum TestCase { 87 UNSECURE, SECURE, PERMISSION; 88 public void run(String name) throws Exception { 89 System.out.println("Running test case: " + name()); 90 switch (this) { 91 case UNSECURE: 92 testUnsecure(name); 93 break; 94 case SECURE: 95 testSecure(name); 96 break; 97 case PERMISSION: 98 testPermission(name); 99 break; 100 default: 101 throw new Error("Unknown test case: "+this); 102 } 103 } 104 public String loggerName(String name) { 105 return name().toLowerCase(Locale.ROOT) + "." + name; 106 } 107 } 108 109 public static void main(String... args) throws Exception { 110 111 Locale defaultLocale = Locale.getDefault(); 112 113 if (args == null || args.length == 0) { 114 args = new String[] { 115 TestCase.UNSECURE.name(), 116 TestCase.SECURE.name() 117 }; 118 } 119 120 for (String testName : args) { 121 TestCase test = TestCase.valueOf(testName); 122 try { 123 test.run(test.loggerName("foo.bar")); 124 } finally { 125 Locale.setDefault(defaultLocale); 126 } 127 } 128 } 129 130 /** 131 * Test without security manager. 132 * @param loggerName The logger to use. 133 * @throws Exception if the test fails. 134 */ 135 public static void testUnsecure(String loggerName) throws Exception { 136 if (System.getSecurityManager() != null) { 137 throw new Error("Security manager is set"); 138 } 139 test(loggerName); 140 } 141 142 /** 143 * Test with security manager. 144 * @param loggerName The logger to use. 145 * @throws Exception if the test fails. 146 */ 147 public static void testSecure(String loggerName) throws Exception { 148 if (System.getSecurityManager() != null) { 149 throw new Error("Security manager is already set"); 150 } 151 Policy.setPolicy(new SimplePolicy(TestCase.SECURE)); 152 System.setSecurityManager(new SecurityManager()); 153 test(loggerName); 154 } 155 156 /** 157 * Test the LoggingPermission("control") is required. 158 * @param loggerName The logger to use. 159 */ 160 public static void testPermission(String loggerName) { 161 if (System.getSecurityManager() != null) { 162 throw new Error("Security manager is already set"); 163 } 164 Policy.setPolicy(new SimplePolicy(TestCase.PERMISSION)); 165 System.setSecurityManager(new SecurityManager()); 166 final ResourceBundle bundle = ResourceBundle.getBundle(LIST_BUNDLE_NAME); 167 Logger foobar = Logger.getLogger(loggerName); 168 try { 169 foobar.setResourceBundle(bundle); 170 throw new RuntimeException("Permission not checked!"); 171 } catch (AccessControlException x) { 172 if (x.getPermission() instanceof LoggingPermission) { 173 if ("control".equals(x.getPermission().getName())) { 174 System.out.println("Got expected exception: " + x); 175 return; 176 } 177 } 178 throw new RuntimeException("Unexpected exception: "+x, x); 179 } 180 181 } 182 183 static String getBaseName(ResourceBundle bundle) { 184 return bundle == null ? null : bundle.getBaseBundleName(); 185 } 186 187 public static void test(String loggerName) throws Exception { 188 189 final ResourceBundle bundle = ResourceBundle.getBundle(LIST_BUNDLE_NAME); 190 Logger foobar = Logger.getLogger(loggerName); 191 192 // Checks that IAE is thrown if the bundle has a null base name. 193 try { 194 foobar.setResourceBundle(new ListBundle()); 195 throw new RuntimeException("Expected exception not raised!"); 196 } catch (IllegalArgumentException x) { 197 System.out.println("Got expected exception: " + x); 198 } 199 200 // Verify that resource bundle was not set. 201 if (foobar.getResourceBundle() != null) { 202 throw new RuntimeException("Unexpected bundle: " 203 + foobar.getResourceBundle()); 204 } 205 if (foobar.getResourceBundleName() != null) { 206 throw new RuntimeException("Unexpected bundle: " 207 + foobar.getResourceBundleName()); 208 } 209 210 // Set acceptable resource bundle on logger. 211 foobar.setResourceBundle(bundle); 212 213 // check that the bundle has been set correctly 214 if (bundle != foobar.getResourceBundle()) { 215 throw new RuntimeException("Unexpected bundle: " 216 + foobar.getResourceBundle()); 217 } 218 if (!Objects.equals(getBaseName(bundle), foobar.getResourceBundleName())) { 219 throw new RuntimeException("Unexpected bundle name: " 220 + foobar.getResourceBundleName()); 221 } 222 223 // Check that we can replace the bundle with a bundle of the same name. 224 final ResourceBundle bundle_fr = 225 ResourceBundle.getBundle(LIST_BUNDLE_NAME, Locale.FRENCH); 226 foobar.setResourceBundle(bundle_fr); 227 228 if (bundle_fr != foobar.getResourceBundle()) { 229 throw new RuntimeException("Unexpected bundle: " 230 + foobar.getResourceBundle()); 231 } 232 if (!Objects.equals(getBaseName(bundle_fr), foobar.getResourceBundleName())) { 233 throw new RuntimeException("Unexpected bundle name: " 234 + foobar.getResourceBundleName()); 235 } 236 237 // Create a child logger 238 Logger foobaz = Logger.getLogger(loggerName + ".baz"); 239 240 // Check that the child logger does not have a bundle set locally 241 if (foobaz.getResourceBundle() != null) { 242 throw new RuntimeException("Unexpected bundle: " 243 + foobar.getResourceBundle()); 244 } 245 if (foobaz.getResourceBundleName() != null) { 246 throw new RuntimeException("Unexpected bundle: " 247 + foobar.getResourceBundleName()); 248 } 249 250 251 // Add a handler on the child logger. 252 final TestHandler handler = new TestHandler(); 253 foobaz.addHandler(handler); 254 255 // log a message on the child logger 256 foobaz.severe("dummy"); 257 258 // checks that the message has been logged with the bundle 259 // inherited from the parent logger 260 if (!LIST_BUNDLE_NAME.equals(handler.lastBundleName)) { 261 throw new RuntimeException("Unexpected bundle name: " 262 + handler.lastBundleName); 263 } 264 if (!bundle_fr.equals(handler.lastBundle)) { 265 throw new RuntimeException("Unexpected bundle: " 266 + handler.lastBundle); 267 } 268 269 // Check that we can get set a bundle on the child logger 270 // using Logger.getLogger. 271 foobaz = Logger.getLogger(loggerName + ".baz", PROPERTY_BUNDLE_NAME); 272 273 // check that the child logger has the correct bundle. 274 // it should no longer inherit it from its parent. 275 if (!PROPERTY_BUNDLE_NAME.equals(foobaz.getResourceBundleName())) { 276 throw new RuntimeException("Unexpected bundle name: " 277 + foobaz.getResourceBundleName()); 278 } 279 if (!PROPERTY_BUNDLE_NAME.equals(foobaz.getResourceBundle().getBaseBundleName())) { 280 throw new RuntimeException("Unexpected bundle name: " 281 + foobaz.getResourceBundle().getBaseBundleName()); 282 } 283 284 // log a message on the child logger 285 foobaz.severe("dummy"); 286 287 // check that the last published log record has the appropriate 288 // bundle. 289 if (!PROPERTY_BUNDLE_NAME.equals(handler.lastBundleName)) { 290 throw new RuntimeException("Unexpected bundle name: " 291 + handler.lastBundleName); 292 } 293 if (foobaz.getResourceBundle() != handler.lastBundle) { 294 throw new RuntimeException("Unexpected bundle: " 295 + handler.lastBundle); 296 } 297 298 // try to set a bundle that has a different name, and checks that 299 // it fails in IAE. 300 try { 301 foobaz.setResourceBundle(bundle_fr); 302 throw new RuntimeException("Expected exception not raised!"); 303 } catch (IllegalArgumentException x) { 304 System.out.println("Got expected exception: " + x); 305 } 306 307 // Test with a subclass of logger which overrides 308 // getResourceBundle() and getResourceBundleName() 309 Logger customLogger = new Logger(foobar.getName()+".bie", null) { 310 @Override 311 public ResourceBundle getResourceBundle() { 312 return bundle_fr; 313 } 314 315 @Override 316 public String getResourceBundleName() { 317 return PROPERTY_BUNDLE_NAME; 318 } 319 }; 320 321 final TestHandler handler2 = new TestHandler(); 322 customLogger.addHandler(handler2); 323 customLogger.setLevel(Level.FINE); 324 LogManager.getLogManager().addLogger(customLogger); 325 326 Logger l = Logger.getLogger(customLogger.getName()); 327 if (l != customLogger) { 328 throw new RuntimeException("Wrong logger: " + l); 329 } 330 331 // log on the custom logger. 332 customLogger.fine("dummy"); 333 334 // check that the log record had the correct bundle. 335 if (! PROPERTY_BUNDLE_NAME.equals(handler2.lastBundleName)) { 336 throw new RuntimeException("Unexpected bundle name: " 337 + handler2.lastBundleName); 338 } 339 if (! PROPERTY_BUNDLE_NAME.equals(customLogger.getResourceBundleName())) { 340 throw new RuntimeException("Unexpected bundle name: " 341 + customLogger.getResourceBundleName()); 342 } 343 if (bundle_fr != handler2.lastBundle) { 344 throw new RuntimeException("Unexpected bundle: " 345 + handler2.lastBundle); 346 } 347 if (bundle_fr != customLogger.getResourceBundle()) { 348 throw new RuntimeException("Unexpected bundle: " 349 + customLogger.getResourceBundle()); 350 } 351 352 // Do the same thing again with a child of the custom logger. 353 Logger biebar = Logger.getLogger(customLogger.getName() + ".bar"); 354 biebar.fine("dummy"); 355 356 // because getResourceBundleName() is called on parent logger 357 // we will have handler2.lastBundleName = PROPERTY_BUNDLE_NAME 358 if (!PROPERTY_BUNDLE_NAME.equals(handler2.lastBundleName)) { 359 throw new RuntimeException("Unexpected bundle name: " 360 + handler2.lastBundleName); 361 } 362 // because getResourceBundle() is not called on parent logger 363 // we will have getBaseName(handler2.lastBundle) = PROPERTY_BUNDLE_NAME 364 // and not handler2.lastBundle = bundle_fr 365 if (handler2.lastBundle == null) { 366 throw new RuntimeException("Unexpected bundle: " 367 + handler2.lastBundle); 368 } 369 if (!PROPERTY_BUNDLE_NAME.equals(getBaseName(handler2.lastBundle))) { 370 throw new RuntimeException("Unexpected bundle name: " 371 + getBaseName(handler2.lastBundle)); 372 } 373 } 374 375 public static class SimplePolicy extends Policy { 376 377 final Permissions permissions; 378 public SimplePolicy(TestCase test) { 379 permissions = new Permissions(); 380 if (test != TestCase.PERMISSION) { 381 permissions.add(new LoggingPermission("control", null)); 382 } 383 // required for calling Locale.setDefault in the test. 384 permissions.add(new PropertyPermission("user.language", "write")); 385 } 386 387 @Override 388 public boolean implies(ProtectionDomain domain, Permission permission) { 389 return permissions.implies(permission); 390 } 391 } 392 393 }