src/share/classes/java/util/logging/Logger.java

Print this page


   1 /*
   2  * Copyright (c) 2000, 2006, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 166     private static final int offValue = Level.OFF.intValue();
 167     private LogManager manager;
 168     private String name;
 169     private final CopyOnWriteArrayList<Handler> handlers =
 170         new CopyOnWriteArrayList<Handler>();
 171     private String resourceBundleName;
 172     private volatile boolean useParentHandlers = true;
 173     private volatile Filter filter;
 174     private boolean anonymous;
 175 
 176     private ResourceBundle catalog;     // Cached resource bundle
 177     private String catalogName;         // name associated with catalog
 178     private Locale catalogLocale;       // locale associated with catalog
 179 
 180     // The fields relating to parent-child relationships and levels
 181     // are managed under a separate lock, the treeLock.
 182     private static Object treeLock = new Object();
 183     // We keep weak references from parents to children, but strong
 184     // references from children to parents.
 185     private volatile Logger parent;    // our nearest parent.
 186     private ArrayList<WeakReference<Logger>> kids;   // WeakReferences to loggers that have us as parent
 187     private volatile Level levelObject;
 188     private volatile int levelValue;  // current effective level value
 189 
 190     /**
 191      * GLOBAL_LOGGER_NAME is a name for the global logger.
 192      *
 193      * @since 1.6
 194      */
 195     public static final String GLOBAL_LOGGER_NAME = "global";
 196 
 197     /**
 198      * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
 199      *
 200      * @return global logger object
 201      * @since 1.7
 202      */
 203     public static final Logger getGlobal() {
 204         return global;
 205     }
 206 


 349     /**
 350      * Create an anonymous Logger.  The newly created Logger is not
 351      * registered in the LogManager namespace.  There will be no
 352      * access checks on updates to the logger.
 353      * <p>
 354      * This factory method is primarily intended for use from applets.
 355      * Because the resulting Logger is anonymous it can be kept private
 356      * by the creating class.  This removes the need for normal security
 357      * checks, which in turn allows untrusted applet code to update
 358      * the control state of the Logger.  For example an applet can do
 359      * a setLevel or an addHandler on an anonymous Logger.
 360      * <p>
 361      * Even although the new logger is anonymous, it is configured
 362      * to have the root logger ("") as its parent.  This means that
 363      * by default it inherits its effective level and handlers
 364      * from the root logger.
 365      * <p>
 366      *
 367      * @return a newly created private Logger
 368      */
 369     public static synchronized Logger getAnonymousLogger() {
 370         LogManager manager = LogManager.getLogManager();
 371         Logger result = new Logger(null, null);
 372         result.anonymous = true;
 373         Logger root = manager.getLogger("");
 374         result.doSetParent(root);
 375         return result;
 376     }
 377 
 378     /**
 379      * Create an anonymous Logger.  The newly created Logger is not
 380      * registered in the LogManager namespace.  There will be no
 381      * access checks on updates to the logger.
 382      * <p>
 383      * This factory method is primarily intended for use from applets.
 384      * Because the resulting Logger is anonymous it can be kept private
 385      * by the creating class.  This removes the need for normal security
 386      * checks, which in turn allows untrusted applet code to update
 387      * the control state of the Logger.  For example an applet can do
 388      * a setLevel or an addHandler on an anonymous Logger.
 389      * <p>
 390      * Even although the new logger is anonymous, it is configured
 391      * to have the root logger ("") as its parent.  This means that
 392      * by default it inherits its effective level and handlers
 393      * from the root logger.
 394      * <p>
 395      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 396      *                          messages for this logger.
 397      *          May be null if none of the messages require localization.
 398      * @return a newly created private Logger
 399      * @throws MissingResourceException if the resourceBundleName is non-null and
 400      *             no corresponding resource can be found.
 401      */
 402     public static synchronized Logger getAnonymousLogger(String resourceBundleName) {
 403         LogManager manager = LogManager.getLogManager();


 404         Logger result = new Logger(null, resourceBundleName);
 405         result.anonymous = true;
 406         Logger root = manager.getLogger("");
 407         result.doSetParent(root);
 408         return result;
 409     }
 410 
 411     /**
 412      * Retrieve the localization resource bundle for this
 413      * logger for the current default locale.  Note that if
 414      * the result is null, then the Logger will use a resource
 415      * bundle inherited from its parent.
 416      *
 417      * @return localization bundle (may be null)
 418      */
 419     public ResourceBundle getResourceBundle() {
 420         return findResourceBundle(getResourceBundleName());
 421     }
 422 
 423     /**


1363      *             the caller does not have LoggingPermission("control").
1364      */
1365     public void setParent(Logger parent) {
1366         if (parent == null) {
1367             throw new NullPointerException();
1368         }
1369         manager.checkAccess();
1370         doSetParent(parent);
1371     }
1372 
1373     // Private method to do the work for parenting a child
1374     // Logger onto a parent logger.
1375     private void doSetParent(Logger newParent) {
1376 
1377         // System.err.println("doSetParent \"" + getName() + "\" \""
1378         //                              + newParent.getName() + "\"");
1379 
1380         synchronized (treeLock) {
1381 
1382             // Remove ourself from any previous parent.

1383             if (parent != null) {
1384                 // assert parent.kids != null;
1385                 for (Iterator<WeakReference<Logger>> iter = parent.kids.iterator(); iter.hasNext(); ) {
1386                     WeakReference<Logger> ref =  iter.next();
1387                     Logger kid =  ref.get();
1388                     if (kid == this) {

1389                         iter.remove();
1390                         break;


1391                     }
1392                 }
1393                 // We have now removed ourself from our parents' kids.
1394             }
1395 
1396             // Set our new parent.
1397             parent = newParent;
1398             if (parent.kids == null) {
1399                 parent.kids = new ArrayList<WeakReference<Logger>>(2);
1400             }
1401             parent.kids.add(new WeakReference<Logger>(this));





1402 
1403             // As a result of the reparenting, the effective level
1404             // may have changed for us and our children.
1405             updateEffectiveLevel();
1406 
1407         }
1408     }
1409 















1410     // Recalculate the effective level for this node and
1411     // recursively for our children.
1412 
1413     private void updateEffectiveLevel() {
1414         // assert Thread.holdsLock(treeLock);
1415 
1416         // Figure out our current effective level.
1417         int newLevelValue;
1418         if (levelObject != null) {
1419             newLevelValue = levelObject.intValue();
1420         } else {
1421             if (parent != null) {
1422                 newLevelValue = parent.levelValue;
1423             } else {
1424                 // This may happen during initialization.
1425                 newLevelValue = Level.INFO.intValue();
1426             }
1427         }
1428 
1429         // If our effective value hasn't changed, we're done.
1430         if (levelValue == newLevelValue) {
1431             return;
1432         }
1433 
1434         levelValue = newLevelValue;
1435 
1436         // System.err.println("effective level: \"" + getName() + "\" := " + level);
1437 
1438         // Recursively update the level on each of our kids.
1439         if (kids != null) {
1440             for (int i = 0; i < kids.size(); i++) {
1441                 WeakReference<Logger> ref = kids.get(i);
1442                 Logger kid =  ref.get();
1443                 if (kid != null) {
1444                     kid.updateEffectiveLevel();
1445                 }
1446             }
1447         }
1448     }
1449 
1450 
1451     // Private method to get the potentially inherited
1452     // resource bundle name for this Logger.
1453     // May return null
1454     private String getEffectiveResourceBundleName() {
1455         Logger target = this;
1456         while (target != null) {
1457             String rbn = target.getResourceBundleName();
1458             if (rbn != null) {
1459                 return rbn;
1460             }
1461             target = target.getParent();
   1 /*
   2  * Copyright (c) 2000, 2010, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 166     private static final int offValue = Level.OFF.intValue();
 167     private LogManager manager;
 168     private String name;
 169     private final CopyOnWriteArrayList<Handler> handlers =
 170         new CopyOnWriteArrayList<Handler>();
 171     private String resourceBundleName;
 172     private volatile boolean useParentHandlers = true;
 173     private volatile Filter filter;
 174     private boolean anonymous;
 175 
 176     private ResourceBundle catalog;     // Cached resource bundle
 177     private String catalogName;         // name associated with catalog
 178     private Locale catalogLocale;       // locale associated with catalog
 179 
 180     // The fields relating to parent-child relationships and levels
 181     // are managed under a separate lock, the treeLock.
 182     private static Object treeLock = new Object();
 183     // We keep weak references from parents to children, but strong
 184     // references from children to parents.
 185     private volatile Logger parent;    // our nearest parent.
 186     private ArrayList<LogManager.LoggerWeakRef> kids;   // WeakReferences to loggers that have us as parent
 187     private volatile Level levelObject;
 188     private volatile int levelValue;  // current effective level value
 189 
 190     /**
 191      * GLOBAL_LOGGER_NAME is a name for the global logger.
 192      *
 193      * @since 1.6
 194      */
 195     public static final String GLOBAL_LOGGER_NAME = "global";
 196 
 197     /**
 198      * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
 199      *
 200      * @return global logger object
 201      * @since 1.7
 202      */
 203     public static final Logger getGlobal() {
 204         return global;
 205     }
 206 


 349     /**
 350      * Create an anonymous Logger.  The newly created Logger is not
 351      * registered in the LogManager namespace.  There will be no
 352      * access checks on updates to the logger.
 353      * <p>
 354      * This factory method is primarily intended for use from applets.
 355      * Because the resulting Logger is anonymous it can be kept private
 356      * by the creating class.  This removes the need for normal security
 357      * checks, which in turn allows untrusted applet code to update
 358      * the control state of the Logger.  For example an applet can do
 359      * a setLevel or an addHandler on an anonymous Logger.
 360      * <p>
 361      * Even although the new logger is anonymous, it is configured
 362      * to have the root logger ("") as its parent.  This means that
 363      * by default it inherits its effective level and handlers
 364      * from the root logger.
 365      * <p>
 366      *
 367      * @return a newly created private Logger
 368      */
 369     public static Logger getAnonymousLogger() {
 370         return getAnonymousLogger(null);





 371     }
 372 
 373     /**
 374      * Create an anonymous Logger.  The newly created Logger is not
 375      * registered in the LogManager namespace.  There will be no
 376      * access checks on updates to the logger.
 377      * <p>
 378      * This factory method is primarily intended for use from applets.
 379      * Because the resulting Logger is anonymous it can be kept private
 380      * by the creating class.  This removes the need for normal security
 381      * checks, which in turn allows untrusted applet code to update
 382      * the control state of the Logger.  For example an applet can do
 383      * a setLevel or an addHandler on an anonymous Logger.
 384      * <p>
 385      * Even although the new logger is anonymous, it is configured
 386      * to have the root logger ("") as its parent.  This means that
 387      * by default it inherits its effective level and handlers
 388      * from the root logger.
 389      * <p>
 390      * @param   resourceBundleName  name of ResourceBundle to be used for localizing
 391      *                          messages for this logger.
 392      *          May be null if none of the messages require localization.
 393      * @return a newly created private Logger
 394      * @throws MissingResourceException if the resourceBundleName is non-null and
 395      *             no corresponding resource can be found.
 396      */
 397     public static synchronized Logger getAnonymousLogger(String resourceBundleName) {
 398         LogManager manager = LogManager.getLogManager();
 399         // cleanup some Loggers that have been GC'ed
 400         manager.drainLoggerRefQueueBounded();
 401         Logger result = new Logger(null, resourceBundleName);
 402         result.anonymous = true;
 403         Logger root = manager.getLogger("");
 404         result.doSetParent(root);
 405         return result;
 406     }
 407 
 408     /**
 409      * Retrieve the localization resource bundle for this
 410      * logger for the current default locale.  Note that if
 411      * the result is null, then the Logger will use a resource
 412      * bundle inherited from its parent.
 413      *
 414      * @return localization bundle (may be null)
 415      */
 416     public ResourceBundle getResourceBundle() {
 417         return findResourceBundle(getResourceBundleName());
 418     }
 419 
 420     /**


1360      *             the caller does not have LoggingPermission("control").
1361      */
1362     public void setParent(Logger parent) {
1363         if (parent == null) {
1364             throw new NullPointerException();
1365         }
1366         manager.checkAccess();
1367         doSetParent(parent);
1368     }
1369 
1370     // Private method to do the work for parenting a child
1371     // Logger onto a parent logger.
1372     private void doSetParent(Logger newParent) {
1373 
1374         // System.err.println("doSetParent \"" + getName() + "\" \""
1375         //                              + newParent.getName() + "\"");
1376 
1377         synchronized (treeLock) {
1378 
1379             // Remove ourself from any previous parent.
1380             LogManager.LoggerWeakRef ref = null;
1381             if (parent != null) {
1382                 // assert parent.kids != null;
1383                 for (Iterator<LogManager.LoggerWeakRef> iter = parent.kids.iterator(); iter.hasNext(); ) {
1384                     ref = iter.next();
1385                     Logger kid =  ref.get();
1386                     if (kid == this) {
1387                         // ref is used down below to complete the reparenting
1388                         iter.remove();
1389                         break;
1390                     } else {
1391                         ref = null;
1392                     }
1393                 }
1394                 // We have now removed ourself from our parents' kids.
1395             }
1396 
1397             // Set our new parent.
1398             parent = newParent;
1399             if (parent.kids == null) {
1400                 parent.kids = new ArrayList<LogManager.LoggerWeakRef>(2);
1401             }
1402             if (ref == null) {
1403                 // we didn't have a previous parent
1404                 ref = manager.new LoggerWeakRef(this);
1405             }
1406             ref.setParentRef(new WeakReference<Logger>(parent));
1407             parent.kids.add(ref);
1408 
1409             // As a result of the reparenting, the effective level
1410             // may have changed for us and our children.
1411             updateEffectiveLevel();
1412 
1413         }
1414     }
1415 
1416     // Package-level method.
1417     // Remove the weak reference for the specified child Logger from the
1418     // kid list. We should only be called from LoggerWeakRef.dispose().
1419     final void removeChildLogger(LogManager.LoggerWeakRef child) {
1420         synchronized (treeLock) {
1421             for (Iterator<LogManager.LoggerWeakRef> iter = kids.iterator(); iter.hasNext(); ) {
1422                 LogManager.LoggerWeakRef ref = iter.next();
1423                 if (ref == child) {
1424                     iter.remove();
1425                     return;
1426                 }
1427             }
1428         }
1429     }
1430 
1431     // Recalculate the effective level for this node and
1432     // recursively for our children.
1433 
1434     private void updateEffectiveLevel() {
1435         // assert Thread.holdsLock(treeLock);
1436 
1437         // Figure out our current effective level.
1438         int newLevelValue;
1439         if (levelObject != null) {
1440             newLevelValue = levelObject.intValue();
1441         } else {
1442             if (parent != null) {
1443                 newLevelValue = parent.levelValue;
1444             } else {
1445                 // This may happen during initialization.
1446                 newLevelValue = Level.INFO.intValue();
1447             }
1448         }
1449 
1450         // If our effective value hasn't changed, we're done.
1451         if (levelValue == newLevelValue) {
1452             return;
1453         }
1454 
1455         levelValue = newLevelValue;
1456 
1457         // System.err.println("effective level: \"" + getName() + "\" := " + level);
1458 
1459         // Recursively update the level on each of our kids.
1460         if (kids != null) {
1461             for (int i = 0; i < kids.size(); i++) {
1462                 LogManager.LoggerWeakRef ref = kids.get(i);
1463                 Logger kid =  ref.get();
1464                 if (kid != null) {
1465                     kid.updateEffectiveLevel();
1466                 }
1467             }
1468         }
1469     }
1470 
1471 
1472     // Private method to get the potentially inherited
1473     // resource bundle name for this Logger.
1474     // May return null
1475     private String getEffectiveResourceBundleName() {
1476         Logger target = this;
1477         while (target != null) {
1478             String rbn = target.getResourceBundleName();
1479             if (rbn != null) {
1480                 return rbn;
1481             }
1482             target = target.getParent();