OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [util/] [logging/] [Logger.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* Logger.java -- a class for logging messages
2
   Copyright (C) 2002, 2004, 2006, 2007 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.util.logging;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import java.util.List;
44
import java.util.MissingResourceException;
45
import java.util.ResourceBundle;
46
import java.security.AccessController;
47
import java.security.PrivilegedAction;
48
 
49
/**
50
 * A Logger is used for logging information about events. Usually, there is a
51
 * seprate logger for each subsystem or component, although there is a shared
52
 * instance for components that make only occasional use of the logging
53
 * framework.
54
 * <p>
55
 * It is common to name a logger after the name of a corresponding Java package.
56
 * Loggers are organized into a hierarchical namespace; for example, the logger
57
 * <code>"org.gnu.foo"</code> is the <em>parent</em> of logger
58
 * <code>"org.gnu.foo.bar"</code>.
59
 * <p>
60
 * A logger for a named subsystem can be obtained through {@link
61
 * java.util.logging.Logger#getLogger(java.lang.String)}. However, only code
62
 * which has been granted the permission to control the logging infrastructure
63
 * will be allowed to customize that logger. Untrusted code can obtain a
64
 * private, anonymous logger through {@link #getAnonymousLogger()} if it wants
65
 * to perform any modifications to the logger.
66
 * <p>
67
 * FIXME: Write more documentation.
68
 *
69
 * @author Sascha Brawer (brawer@acm.org)
70
 */
71
public class Logger
72
{
73
  static final Logger root = new Logger("", null);
74
 
75
  /**
76
   * A logger provided to applications that make only occasional use of the
77
   * logging framework, typically early prototypes. Serious products are
78
   * supposed to create and use their own Loggers, so they can be controlled
79
   * individually.
80
   */
81
  public static final Logger global;
82
 
83
  /**
84
   * Use to lock methods on this class instead of calling synchronize on methods
85
   * to avoid deadlocks. Yeah, no kidding, we got them :)
86
   */
87
  private static final Object[] lock = new Object[0];
88
 
89
  static
90
    {
91
      // Our class might be initialized from an unprivileged context
92
      global = (Logger) AccessController.doPrivileged(new PrivilegedAction()
93
      {
94
        public Object run()
95
        {
96
          return getLogger("global");
97
        }
98
      });
99
    }
100
 
101
  /**
102
   * The name of the Logger, or <code>null</code> if the logger is anonymous.
103
   * <p>
104
   * A previous version of the GNU Classpath implementation granted untrusted
105
   * code the permission to control any logger whose name was null. However,
106
   * test code revealed that the Sun J2SE 1.4 reference implementation enforces
107
   * the security control for any logger that was not created through
108
   * getAnonymousLogger, even if it has a null name. Therefore, a separate flag
109
   * {@link Logger#anonymous} was introduced.
110
   */
111
  private final String name;
112
 
113
  /**
114
   * The name of the resource bundle used for localization.
115
   * <p>
116
   * This variable cannot be declared as <code>final</code> because its value
117
   * can change as a result of calling getLogger(String,String).
118
   */
119
  private String resourceBundleName;
120
 
121
  /**
122
   * The resource bundle used for localization.
123
   * <p>
124
   * This variable cannot be declared as <code>final</code> because its value
125
   * can change as a result of calling getLogger(String,String).
126
   */
127
  private ResourceBundle resourceBundle;
128
 
129
  private Filter filter;
130
 
131
  private final List handlerList = new java.util.ArrayList(4);
132
 
133
  private Handler[] handlers = new Handler[0];
134
 
135
  /**
136
   * Indicates whether or not this logger is anonymous. While a
137
   * LoggingPermission is required for any modifications to a normal logger,
138
   * untrusted code can obtain an anonymous logger and modify it according to
139
   * its needs.
140
   * <p>
141
   * A previous version of the GNU Classpath implementation granted access to
142
   * every logger whose name was null. However, test code revealed that the Sun
143
   * J2SE 1.4 reference implementation enforces the security control for any
144
   * logger that was not created through getAnonymousLogger, even if it has a
145
   * null name.
146
   */
147
  private boolean anonymous;
148
 
149
  private boolean useParentHandlers;
150
 
151
  private Level level;
152
 
153
  private Logger parent;
154
 
155
  /**
156
   * Constructs a Logger for a subsystem. Most applications do not need to
157
   * create new Loggers explicitly; instead, they should call the static factory
158
   * methods {@link #getLogger(java.lang.String,java.lang.String) getLogger}
159
   * (with ResourceBundle for localization) or
160
   * {@link #getLogger(java.lang.String) getLogger} (without ResourceBundle),
161
   * respectively.
162
   *
163
   * @param name the name for the logger, for example "java.awt" or
164
   *            "com.foo.bar". The name should be based on the name of the
165
   *            package issuing log records and consist of dot-separated Java
166
   *            identifiers.
167
   * @param resourceBundleName the name of a resource bundle for localizing
168
   *            messages, or <code>null</code> to indicate that messages do
169
   *            not need to be localized.
170
   * @throws java.util.MissingResourceException if
171
   *             <code>resourceBundleName</code> is not <code>null</code>
172
   *             and no such bundle could be located.
173
   */
174
  protected Logger(String name, String resourceBundleName)
175
      throws MissingResourceException
176
  {
177
    this.name = name;
178
    this.resourceBundleName = resourceBundleName;
179
 
180
    if (resourceBundleName == null)
181
      resourceBundle = null;
182
    else
183
      resourceBundle = ResourceBundle.getBundle(resourceBundleName);
184
 
185
    level = null;
186
 
187
    /*
188
     * This is null when the root logger is being constructed, and the root
189
     * logger afterwards.
190
     */
191
    parent = root;
192
 
193
    useParentHandlers = (parent != null);
194
  }
195
 
196
  /**
197
   * Finds a registered logger for a subsystem, or creates one in case no logger
198
   * has been registered yet.
199
   *
200
   * @param name the name for the logger, for example "java.awt" or
201
   *            "com.foo.bar". The name should be based on the name of the
202
   *            package issuing log records and consist of dot-separated Java
203
   *            identifiers.
204
   * @throws IllegalArgumentException if a logger for the subsystem identified
205
   *             by <code>name</code> has already been created, but uses a a
206
   *             resource bundle for localizing messages.
207
   * @throws NullPointerException if <code>name</code> is <code>null</code>.
208
   * @return a logger for the subsystem specified by <code>name</code> that
209
   *         does not localize messages.
210
   */
211
  public static Logger getLogger(String name)
212
  {
213
    return getLogger(name, null);
214
  }
215
 
216
  /**
217
   * Finds a registered logger for a subsystem, or creates one in case no logger
218
   * has been registered yet.
219
   * <p>
220
   * If a logger with the specified name has already been registered, the
221
   * behavior depends on the resource bundle that is currently associated with
222
   * the existing logger.
223
   * <ul>
224
   * <li>If the existing logger uses the same resource bundle as specified by
225
   * <code>resourceBundleName</code>, the existing logger is returned.</li>
226
   * <li>If the existing logger currently does not localize messages, the
227
   * existing logger is modified to use the bundle specified by
228
   * <code>resourceBundleName</code>. The existing logger is then returned.
229
   * Therefore, all subsystems currently using this logger will produce
230
   * localized messages from now on.</li>
231
   * <li>If the existing logger already has an associated resource bundle, but
232
   * a different one than specified by <code>resourceBundleName</code>, an
233
   * <code>IllegalArgumentException</code> is thrown.</li>
234
   * </ul>
235
   *
236
   * @param name the name for the logger, for example "java.awt" or
237
   *            "org.gnu.foo". The name should be based on the name of the
238
   *            package issuing log records and consist of dot-separated Java
239
   *            identifiers.
240
   * @param resourceBundleName the name of a resource bundle for localizing
241
   *            messages, or <code>null</code> to indicate that messages do
242
   *            not need to be localized.
243
   * @return a logger for the subsystem specified by <code>name</code>.
244
   * @throws java.util.MissingResourceException if
245
   *             <code>resourceBundleName</code> is not <code>null</code>
246
   *             and no such bundle could be located.
247
   * @throws IllegalArgumentException if a logger for the subsystem identified
248
   *             by <code>name</code> has already been created, but uses a
249
   *             different resource bundle for localizing messages.
250
   * @throws NullPointerException if <code>name</code> is <code>null</code>.
251
   */
252
  public static Logger getLogger(String name, String resourceBundleName)
253
  {
254
    LogManager lm = LogManager.getLogManager();
255
    Logger result;
256
 
257
    if (name == null)
258
      throw new NullPointerException();
259
 
260
    /*
261
     * Without synchronized(lm), it could happen that another thread would
262
     * create a logger between our calls to getLogger and addLogger. While
263
     * addLogger would indicate this by returning false, we could not be sure
264
     * that this other logger was still existing when we called getLogger a
265
     * second time in order to retrieve it -- note that LogManager is only
266
     * allowed to keep weak references to registered loggers, so Loggers can be
267
     * garbage collected at any time in general, and between our call to
268
     * addLogger and our second call go getLogger in particular. Of course, we
269
     * assume here that LogManager.addLogger etc. are synchronizing on the
270
     * global LogManager object. There is a comment in the implementation of
271
     * LogManager.addLogger referring to this comment here, so that any change
272
     * in the synchronization of LogManager will be reflected here.
273
     */
274
    synchronized (lock)
275
      {
276
        synchronized (lm)
277
          {
278
            result = lm.getLogger(name);
279
            if (result == null)
280
              {
281
                boolean couldBeAdded;
282
 
283
                result = new Logger(name, resourceBundleName);
284
                couldBeAdded = lm.addLogger(result);
285
                if (! couldBeAdded)
286
                  throw new IllegalStateException("cannot register new logger");
287
              }
288
            else
289
              {
290
                /*
291
                 * The logger already exists. Make sure it uses the same
292
                 * resource bundle for localizing messages.
293
                 */
294
                String existingBundleName = result.getResourceBundleName();
295
 
296
                /*
297
                 * The Sun J2SE 1.4 reference implementation will return the
298
                 * registered logger object, even if it does not have a resource
299
                 * bundle associated with it. However, it seems to change the
300
                 * resourceBundle of the registered logger to the bundle whose
301
                 * name was passed to getLogger.
302
                 */
303
                if ((existingBundleName == null) &&
304
                    (resourceBundleName != null))
305
                  {
306
                    /*
307
                     * If ResourceBundle.getBundle throws an exception, the
308
                     * existing logger will be unchanged. This would be
309
                     * different if the assignment to resourceBundleName came
310
                     * first.
311
                     */
312
                    result.resourceBundle =
313
                      ResourceBundle.getBundle(resourceBundleName);
314
 
315
                    result.resourceBundleName = resourceBundleName;
316
                    return result;
317
                  }
318
 
319
                if ((existingBundleName != resourceBundleName)
320
                    && ((existingBundleName == null)
321
                        || !existingBundleName.equals(resourceBundleName)))
322
                  {
323
                    throw new IllegalArgumentException();
324
                  }
325
              }
326
          }
327
      }
328
 
329
    return result;
330
  }
331
 
332
  /**
333
   * Creates a new, unnamed logger. Unnamed loggers are not registered in the
334
   * namespace of the LogManager, and no special security permission is required
335
   * for changing their state. Therefore, untrusted applets are able to modify
336
   * their private logger instance obtained through this method.
337
   * <p>
338
   * The parent of the newly created logger will the the root logger, from which
339
   * the level threshold and the handlers are inherited.
340
   */
341
  public static Logger getAnonymousLogger()
342
  {
343
    return getAnonymousLogger(null);
344
  }
345
 
346
  /**
347
   * Creates a new, unnamed logger. Unnamed loggers are not registered in the
348
   * namespace of the LogManager, and no special security permission is required
349
   * for changing their state. Therefore, untrusted applets are able to modify
350
   * their private logger instance obtained through this method.
351
   * <p>
352
   * The parent of the newly created logger will the the root logger, from which
353
   * the level threshold and the handlers are inherited.
354
   *
355
   * @param resourceBundleName the name of a resource bundle for localizing
356
   *            messages, or <code>null</code> to indicate that messages do
357
   *            not need to be localized.
358
   * @throws java.util.MissingResourceException if
359
   *             <code>resourceBundleName</code> is not <code>null</code>
360
   *             and no such bundle could be located.
361
   */
362
  public static Logger getAnonymousLogger(String resourceBundleName)
363
      throws MissingResourceException
364
  {
365
    Logger result;
366
 
367
    result = new Logger(null, resourceBundleName);
368
    result.anonymous = true;
369
    return result;
370
  }
371
 
372
  /**
373
   * Returns the name of the resource bundle that is being used for localizing
374
   * messages.
375
   *
376
   * @return the name of the resource bundle used for localizing messages, or
377
   *         <code>null</code> if the parent's resource bundle is used for
378
   *         this purpose.
379
   */
380
  public String getResourceBundleName()
381
  {
382
    synchronized (lock)
383
      {
384
        return resourceBundleName;
385
      }
386
  }
387
 
388
  /**
389
   * Returns the resource bundle that is being used for localizing messages.
390
   *
391
   * @return the resource bundle used for localizing messages, or
392
   *         <code>null</code> if the parent's resource bundle is used for
393
   *         this purpose.
394
   */
395
  public ResourceBundle getResourceBundle()
396
  {
397
    synchronized (lock)
398
      {
399
        return resourceBundle;
400
      }
401
  }
402
 
403
  /**
404
   * Returns the severity level threshold for this <code>Handler</code>. All
405
   * log records with a lower severity level will be discarded; a log record of
406
   * the same or a higher level will be published unless an installed
407
   * <code>Filter</code> decides to discard it.
408
   *
409
   * @return the severity level below which all log messages will be discarded,
410
   *         or <code>null</code> if the logger inherits the threshold from
411
   *         its parent.
412
   */
413
  public Level getLevel()
414
  {
415
    synchronized (lock)
416
      {
417
        return level;
418
      }
419
  }
420
 
421
  /**
422
   * Returns whether or not a message of the specified level would be logged by
423
   * this logger.
424
   *
425
   * @throws NullPointerException if <code>level</code> is <code>null</code>.
426
   */
427
  public boolean isLoggable(Level level)
428
  {
429
    synchronized (lock)
430
      {
431
        if (this.level != null)
432
          return this.level.intValue() <= level.intValue();
433
 
434
        if (parent != null)
435
          return parent.isLoggable(level);
436
        else
437
          return false;
438
      }
439
  }
440
 
441
  /**
442
   * Sets the severity level threshold for this <code>Handler</code>. All log
443
   * records with a lower severity level will be discarded immediately. A log
444
   * record of the same or a higher level will be published unless an installed
445
   * <code>Filter</code> decides to discard it.
446
   *
447
   * @param level the severity level below which all log messages will be
448
   *            discarded, or <code>null</code> to indicate that the logger
449
   *            should inherit the threshold from its parent.
450
   * @throws SecurityException if this logger is not anonymous, a security
451
   *             manager exists, and the caller is not granted the permission to
452
   *             control the logging infrastructure by having
453
   *             LoggingPermission("control"). Untrusted code can obtain an
454
   *             anonymous logger through the static factory method
455
   *             {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
456
   */
457
  public void setLevel(Level level)
458
  {
459
    synchronized (lock)
460
      {
461
        /*
462
         * An application is allowed to control an anonymous logger without
463
         * having the permission to control the logging infrastructure.
464
         */
465
        if (! anonymous)
466
          LogManager.getLogManager().checkAccess();
467
 
468
        this.level = level;
469
      }
470
  }
471
 
472
  public Filter getFilter()
473
  {
474
    synchronized (lock)
475
      {
476
        return filter;
477
      }
478
  }
479
 
480
  /**
481
   * @throws SecurityException if this logger is not anonymous, a security
482
   *             manager exists, and the caller is not granted the permission to
483
   *             control the logging infrastructure by having
484
   *             LoggingPermission("control"). Untrusted code can obtain an
485
   *             anonymous logger through the static factory method
486
   *             {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
487
   */
488
  public void setFilter(Filter filter) throws SecurityException
489
  {
490
    synchronized (lock)
491
      {
492
        /*
493
         * An application is allowed to control an anonymous logger without
494
         * having the permission to control the logging infrastructure.
495
         */
496
        if (! anonymous)
497
          LogManager.getLogManager().checkAccess();
498
 
499
        this.filter = filter;
500
      }
501
  }
502
 
503
  /**
504
   * Returns the name of this logger.
505
   *
506
   * @return the name of this logger, or <code>null</code> if the logger is
507
   *         anonymous.
508
   */
509
  public String getName()
510
  {
511
    /*
512
     * Note that the name of a logger cannot be changed during its lifetime, so
513
     * no synchronization is needed.
514
     */
515
    return name;
516
  }
517
 
518
  /**
519
   * Passes a record to registered handlers, provided the record is considered
520
   * as loggable both by {@link #isLoggable(Level)} and a possibly installed
521
   * custom {@link #setFilter(Filter) filter}.
522
   * <p>
523
   * If the logger has been configured to use parent handlers, the record will
524
   * be forwarded to the parent of this logger in addition to being processed by
525
   * the handlers registered with this logger.
526
   * <p>
527
   * The other logging methods in this class are convenience methods that merely
528
   * create a new LogRecord and pass it to this method. Therefore, subclasses
529
   * usually just need to override this single method for customizing the
530
   * logging behavior.
531
   *
532
   * @param record the log record to be inspected and possibly forwarded.
533
   */
534
  public void log(LogRecord record)
535
  {
536
    synchronized (lock)
537
      {
538
        if (!isLoggable(record.getLevel()))
539
          return;
540
 
541
        if ((filter != null) && ! filter.isLoggable(record))
542
          return;
543
 
544
        /*
545
         * If no logger name has been set for the log record, use the name of
546
         * this logger.
547
         */
548
        if (record.getLoggerName() == null)
549
          record.setLoggerName(name);
550
 
551
        /*
552
         * Avoid that some other thread is changing the logger hierarchy while
553
         * we are traversing it.
554
         */
555
        synchronized (LogManager.getLogManager())
556
          {
557
            Logger curLogger = this;
558
 
559
            do
560
              {
561
                /*
562
                 * The Sun J2SE 1.4 reference implementation seems to call the
563
                 * filter only for the logger whose log method is called, never
564
                 * for any of its parents. Also, parent loggers publish log
565
                 * record whatever their level might be. This is pretty weird,
566
                 * but GNU Classpath tries to be as compatible as possible to
567
                 * the reference implementation.
568
                 */
569
                for (int i = 0; i < curLogger.handlers.length; i++)
570
                  curLogger.handlers[i].publish(record);
571
 
572
                if (curLogger.getUseParentHandlers() == false)
573
                  break;
574
 
575
                curLogger = curLogger.getParent();
576
              }
577
            while (parent != null);
578
          }
579
      }
580
  }
581
 
582
  public void log(Level level, String message)
583
  {
584
    if (isLoggable(level))
585
      log(level, message, (Object[]) null);
586
  }
587
 
588
  public void log(Level level, String message, Object param)
589
  {
590
    synchronized (lock)
591
      {
592
        if (isLoggable(level))
593
          {
594
            StackTraceElement caller = getCallerStackFrame();
595
            logp(level, caller != null ? caller.getClassName() : "<unknown>",
596
                 caller != null ? caller.getMethodName() : "<unknown>",
597
                 message, param);
598
          }
599
      }
600
  }
601
 
602
  public void log(Level level, String message, Object[] params)
603
  {
604
    synchronized (lock)
605
      {
606
        if (isLoggable(level))
607
          {
608
            StackTraceElement caller = getCallerStackFrame();
609
            logp(level, caller != null ? caller.getClassName() : "<unknown>",
610
                 caller != null ? caller.getMethodName() : "<unknown>",
611
                 message, params);
612
 
613
          }
614
      }
615
  }
616
 
617
  public void log(Level level, String message, Throwable thrown)
618
  {
619
    synchronized (lock)
620
      {
621
        if (isLoggable(level))
622
          {
623
            StackTraceElement caller = getCallerStackFrame();
624
            logp(level, caller != null ? caller.getClassName() : "<unknown>",
625
                 caller != null ? caller.getMethodName() : "<unknown>",
626
                 message, thrown);
627
          }
628
      }
629
  }
630
 
631
  public void logp(Level level, String sourceClass, String sourceMethod,
632
                   String message)
633
  {
634
    synchronized (lock)
635
      {
636
        logp(level, sourceClass, sourceMethod, message, (Object[]) null);
637
      }
638
  }
639
 
640
  public void logp(Level level, String sourceClass, String sourceMethod,
641
                   String message, Object param)
642
  {
643
    synchronized (lock)
644
      {
645
        logp(level, sourceClass, sourceMethod, message, new Object[] { param });
646
      }
647
 
648
  }
649
 
650
  private ResourceBundle findResourceBundle()
651
  {
652
    synchronized (lock)
653
      {
654
        if (resourceBundle != null)
655
          return resourceBundle;
656
 
657
        if (parent != null)
658
          return parent.findResourceBundle();
659
 
660
        return null;
661
      }
662
  }
663
 
664
  private void logImpl(Level level, String sourceClass, String sourceMethod,
665
                       String message, Object[] params)
666
  {
667
    synchronized (lock)
668
      {
669
        LogRecord rec = new LogRecord(level, message);
670
 
671
        rec.setResourceBundle(findResourceBundle());
672
        rec.setSourceClassName(sourceClass);
673
        rec.setSourceMethodName(sourceMethod);
674
        rec.setParameters(params);
675
 
676
        log(rec);
677
      }
678
  }
679
 
680
  public void logp(Level level, String sourceClass, String sourceMethod,
681
                   String message, Object[] params)
682
  {
683
    synchronized (lock)
684
      {
685
        logImpl(level, sourceClass, sourceMethod, message, params);
686
      }
687
  }
688
 
689
  public void logp(Level level, String sourceClass, String sourceMethod,
690
                   String message, Throwable thrown)
691
  {
692
    synchronized (lock)
693
      {
694
        LogRecord rec = new LogRecord(level, message);
695
 
696
        rec.setResourceBundle(resourceBundle);
697
        rec.setSourceClassName(sourceClass);
698
        rec.setSourceMethodName(sourceMethod);
699
        rec.setThrown(thrown);
700
 
701
        log(rec);
702
      }
703
  }
704
 
705
  public void logrb(Level level, String sourceClass, String sourceMethod,
706
                    String bundleName, String message)
707
  {
708
    synchronized (lock)
709
      {
710
        logrb(level, sourceClass, sourceMethod, bundleName, message,
711
              (Object[]) null);
712
      }
713
  }
714
 
715
  public void logrb(Level level, String sourceClass, String sourceMethod,
716
                    String bundleName, String message, Object param)
717
  {
718
    synchronized (lock)
719
      {
720
        logrb(level, sourceClass, sourceMethod, bundleName, message,
721
              new Object[] { param });
722
      }
723
  }
724
 
725
  public void logrb(Level level, String sourceClass, String sourceMethod,
726
                    String bundleName, String message, Object[] params)
727
  {
728
    synchronized (lock)
729
      {
730
        LogRecord rec = new LogRecord(level, message);
731
 
732
        rec.setResourceBundleName(bundleName);
733
        rec.setSourceClassName(sourceClass);
734
        rec.setSourceMethodName(sourceMethod);
735
        rec.setParameters(params);
736
 
737
        log(rec);
738
      }
739
  }
740
 
741
  public void logrb(Level level, String sourceClass, String sourceMethod,
742
                    String bundleName, String message, Throwable thrown)
743
  {
744
    synchronized (lock)
745
      {
746
        LogRecord rec = new LogRecord(level, message);
747
 
748
        rec.setResourceBundleName(bundleName);
749
        rec.setSourceClassName(sourceClass);
750
        rec.setSourceMethodName(sourceMethod);
751
        rec.setThrown(thrown);
752
 
753
        log(rec);
754
      }
755
  }
756
 
757
  public void entering(String sourceClass, String sourceMethod)
758
  {
759
    synchronized (lock)
760
      {
761
        if (isLoggable(Level.FINER))
762
          logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
763
      }
764
  }
765
 
766
  public void entering(String sourceClass, String sourceMethod, Object param)
767
  {
768
    synchronized (lock)
769
      {
770
        if (isLoggable(Level.FINER))
771
          logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param);
772
      }
773
  }
774
 
775
  public void entering(String sourceClass, String sourceMethod, Object[] params)
776
  {
777
    synchronized (lock)
778
      {
779
        if (isLoggable(Level.FINER))
780
          {
781
            CPStringBuilder buf = new CPStringBuilder(80);
782
            buf.append("ENTRY");
783
            for (int i = 0; i < params.length; i++)
784
              {
785
                buf.append(" {");
786
                buf.append(i);
787
                buf.append('}');
788
              }
789
 
790
            logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params);
791
          }
792
      }
793
  }
794
 
795
  public void exiting(String sourceClass, String sourceMethod)
796
  {
797
    synchronized (lock)
798
      {
799
        if (isLoggable(Level.FINER))
800
          logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
801
      }
802
  }
803
 
804
  public void exiting(String sourceClass, String sourceMethod, Object result)
805
  {
806
    synchronized (lock)
807
      {
808
        if (isLoggable(Level.FINER))
809
          logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
810
      }
811
  }
812
 
813
  public void throwing(String sourceClass, String sourceMethod, Throwable thrown)
814
  {
815
    synchronized (lock)
816
      {
817
        if (isLoggable(Level.FINER))
818
          logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown);
819
      }
820
  }
821
 
822
  /**
823
   * Logs a message with severity level SEVERE, indicating a serious failure
824
   * that prevents normal program execution. Messages at this level should be
825
   * understandable to an inexperienced, non-technical end user. Ideally, they
826
   * explain in simple words what actions the user can take in order to resolve
827
   * the problem.
828
   *
829
   * @see Level#SEVERE
830
   * @param message the message text, also used as look-up key if the logger is
831
   *            localizing messages with a resource bundle. While it is possible
832
   *            to pass <code>null</code>, this is not recommended, since a
833
   *            logging message without text is unlikely to be helpful.
834
   */
835
  public void severe(String message)
836
  {
837
    synchronized (lock)
838
      {
839
        if (isLoggable(Level.SEVERE))
840
          log(Level.SEVERE, message);
841
      }
842
  }
843
 
844
  /**
845
   * Logs a message with severity level WARNING, indicating a potential problem
846
   * that does not prevent normal program execution. Messages at this level
847
   * should be understandable to an inexperienced, non-technical end user.
848
   * Ideally, they explain in simple words what actions the user can take in
849
   * order to resolve the problem.
850
   *
851
   * @see Level#WARNING
852
   * @param message the message text, also used as look-up key if the logger is
853
   *            localizing messages with a resource bundle. While it is possible
854
   *            to pass <code>null</code>, this is not recommended, since a
855
   *            logging message without text is unlikely to be helpful.
856
   */
857
  public void warning(String message)
858
  {
859
    synchronized (lock)
860
      {
861
        if (isLoggable(Level.WARNING))
862
          log(Level.WARNING, message);
863
      }
864
  }
865
 
866
  /**
867
   * Logs a message with severity level INFO. {@link Level#INFO} is intended for
868
   * purely informational messages that do not indicate error or warning
869
   * situations. In the default logging configuration, INFO messages will be
870
   * written to the system console. For this reason, the INFO level should be
871
   * used only for messages that are important to end users and system
872
   * administrators. Messages at this level should be understandable to an
873
   * inexperienced, non-technical user.
874
   *
875
   * @param message the message text, also used as look-up key if the logger is
876
   *            localizing messages with a resource bundle. While it is possible
877
   *            to pass <code>null</code>, this is not recommended, since a
878
   *            logging message without text is unlikely to be helpful.
879
   */
880
  public void info(String message)
881
  {
882
    synchronized (lock)
883
      {
884
        if (isLoggable(Level.INFO))
885
          log(Level.INFO, message);
886
      }
887
  }
888
 
889
  /**
890
   * Logs a message with severity level CONFIG. {@link Level#CONFIG} is intended
891
   * for static configuration messages, for example about the windowing
892
   * environment, the operating system version, etc.
893
   *
894
   * @param message the message text, also used as look-up key if the logger is
895
   *            localizing messages with a resource bundle. While it is possible
896
   *            to pass <code>null</code>, this is not recommended, since a
897
   *            logging message without text is unlikely to be helpful.
898
   */
899
  public void config(String message)
900
  {
901
    synchronized (lock)
902
      {
903
        if (isLoggable(Level.CONFIG))
904
          log(Level.CONFIG, message);
905
      }
906
  }
907
 
908
  /**
909
   * Logs a message with severity level FINE. {@link Level#FINE} is intended for
910
   * messages that are relevant for developers using the component generating
911
   * log messages. Examples include minor, recoverable failures, or possible
912
   * inefficiencies.
913
   *
914
   * @param message the message text, also used as look-up key if the logger is
915
   *            localizing messages with a resource bundle. While it is possible
916
   *            to pass <code>null</code>, this is not recommended, since a
917
   *            logging message without text is unlikely to be helpful.
918
   */
919
  public void fine(String message)
920
  {
921
    synchronized (lock)
922
      {
923
        if (isLoggable(Level.FINE))
924
          log(Level.FINE, message);
925
      }
926
  }
927
 
928
  /**
929
   * Logs a message with severity level FINER. {@link Level#FINER} is intended
930
   * for rather detailed tracing, for example entering a method, returning from
931
   * a method, or throwing an exception.
932
   *
933
   * @param message the message text, also used as look-up key if the logger is
934
   *            localizing messages with a resource bundle. While it is possible
935
   *            to pass <code>null</code>, this is not recommended, since a
936
   *            logging message without text is unlikely to be helpful.
937
   */
938
  public void finer(String message)
939
  {
940
    synchronized (lock)
941
      {
942
        if (isLoggable(Level.FINER))
943
          log(Level.FINER, message);
944
      }
945
  }
946
 
947
  /**
948
   * Logs a message with severity level FINEST. {@link Level#FINEST} is intended
949
   * for highly detailed tracing, for example reaching a certain point inside
950
   * the body of a method.
951
   *
952
   * @param message the message text, also used as look-up key if the logger is
953
   *            localizing messages with a resource bundle. While it is possible
954
   *            to pass <code>null</code>, this is not recommended, since a
955
   *            logging message without text is unlikely to be helpful.
956
   */
957
  public void finest(String message)
958
  {
959
    synchronized (lock)
960
      {
961
        if (isLoggable(Level.FINEST))
962
          log(Level.FINEST, message);
963
      }
964
  }
965
 
966
  /**
967
   * Adds a handler to the set of handlers that get notified when a log record
968
   * is to be published.
969
   *
970
   * @param handler the handler to be added.
971
   * @throws NullPointerException if <code>handler</code> is <code>null</code>.
972
   * @throws SecurityException if this logger is not anonymous, a security
973
   *             manager exists, and the caller is not granted the permission to
974
   *             control the logging infrastructure by having
975
   *             LoggingPermission("control"). Untrusted code can obtain an
976
   *             anonymous logger through the static factory method
977
   *             {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
978
   */
979
  public void addHandler(Handler handler) throws SecurityException
980
  {
981
    synchronized (lock)
982
      {
983
        if (handler == null)
984
          throw new NullPointerException();
985
 
986
        /*
987
         * An application is allowed to control an anonymous logger without
988
         * having the permission to control the logging infrastructure.
989
         */
990
        if (! anonymous)
991
          LogManager.getLogManager().checkAccess();
992
 
993
        if (! handlerList.contains(handler))
994
          {
995
            handlerList.add(handler);
996
            handlers = getHandlers();
997
          }
998
      }
999
  }
1000
 
1001
  /**
1002
   * Removes a handler from the set of handlers that get notified when a log
1003
   * record is to be published.
1004
   *
1005
   * @param handler the handler to be removed.
1006
   * @throws SecurityException if this logger is not anonymous, a security
1007
   *             manager exists, and the caller is not granted the permission to
1008
   *             control the logging infrastructure by having
1009
   *             LoggingPermission("control"). Untrusted code can obtain an
1010
   *             anonymous logger through the static factory method {@link
1011
   *             #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
1012
   * @throws NullPointerException if <code>handler</code> is <code>null</code>.
1013
   */
1014
  public void removeHandler(Handler handler) throws SecurityException
1015
  {
1016
    synchronized (lock)
1017
      {
1018
        /*
1019
         * An application is allowed to control an anonymous logger without
1020
         * having the permission to control the logging infrastructure.
1021
         */
1022
        if (! anonymous)
1023
          LogManager.getLogManager().checkAccess();
1024
 
1025
        if (handler == null)
1026
          throw new NullPointerException();
1027
 
1028
        handlerList.remove(handler);
1029
        handlers = getHandlers();
1030
      }
1031
  }
1032
 
1033
  /**
1034
   * Returns the handlers currently registered for this Logger. When a log
1035
   * record has been deemed as being loggable, it will be passed to all
1036
   * registered handlers for publication. In addition, if the logger uses parent
1037
   * handlers (see {@link #getUseParentHandlers() getUseParentHandlers} and
1038
   * {@link #setUseParentHandlers(boolean) setUseParentHandlers}, the log
1039
   * record will be passed to the parent's handlers.
1040
   */
1041
  public Handler[] getHandlers()
1042
  {
1043
    synchronized (lock)
1044
      {
1045
        /*
1046
         * We cannot return our internal handlers array because we do not have
1047
         * any guarantee that the caller would not change the array entries.
1048
         */
1049
        return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]);
1050
      }
1051
  }
1052
 
1053
  /**
1054
   * Returns whether or not this Logger forwards log records to handlers
1055
   * registered for its parent loggers.
1056
   *
1057
   * @return <code>false</code> if this Logger sends log records merely to
1058
   *         Handlers registered with itself; <code>true</code> if this Logger
1059
   *         sends log records not only to Handlers registered with itself, but
1060
   *         also to those Handlers registered with parent loggers.
1061
   */
1062
  public boolean getUseParentHandlers()
1063
  {
1064
    synchronized (lock)
1065
      {
1066
        return useParentHandlers;
1067
      }
1068
  }
1069
 
1070
  /**
1071
   * Sets whether or not this Logger forwards log records to handlers registered
1072
   * for its parent loggers.
1073
   *
1074
   * @param useParentHandlers <code>false</code> to let this Logger send log
1075
   *            records merely to Handlers registered with itself;
1076
   *            <code>true</code> to let this Logger send log records not only
1077
   *            to Handlers registered with itself, but also to those Handlers
1078
   *            registered with parent loggers.
1079
   * @throws SecurityException if this logger is not anonymous, a security
1080
   *             manager exists, and the caller is not granted the permission to
1081
   *             control the logging infrastructure by having
1082
   *             LoggingPermission("control"). Untrusted code can obtain an
1083
   *             anonymous logger through the static factory method
1084
   *             {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
1085
   */
1086
  public void setUseParentHandlers(boolean useParentHandlers)
1087
  {
1088
    synchronized (lock)
1089
      {
1090
        /*
1091
         * An application is allowed to control an anonymous logger without
1092
         * having the permission to control the logging infrastructure.
1093
         */
1094
        if (! anonymous)
1095
          LogManager.getLogManager().checkAccess();
1096
 
1097
        this.useParentHandlers = useParentHandlers;
1098
      }
1099
  }
1100
 
1101
  /**
1102
   * Returns the parent of this logger. By default, the parent is assigned by
1103
   * the LogManager by inspecting the logger's name.
1104
   *
1105
   * @return the parent of this logger (as detemined by the LogManager by
1106
   *         inspecting logger names), the root logger if no other logger has a
1107
   *         name which is a prefix of this logger's name, or <code>null</code>
1108
   *         for the root logger.
1109
   */
1110
  public Logger getParent()
1111
  {
1112
    synchronized (lock)
1113
      {
1114
        return parent;
1115
      }
1116
  }
1117
 
1118
  /**
1119
   * Sets the parent of this logger. Usually, applications do not call this
1120
   * method directly. Instead, the LogManager will ensure that the tree of
1121
   * loggers reflects the hierarchical logger namespace. Basically, this method
1122
   * should not be public at all, but the GNU implementation follows the API
1123
   * specification.
1124
   *
1125
   * @throws NullPointerException if <code>parent</code> is <code>null</code>.
1126
   * @throws SecurityException if this logger is not anonymous, a security
1127
   *             manager exists, and the caller is not granted the permission to
1128
   *             control the logging infrastructure by having
1129
   *             LoggingPermission("control"). Untrusted code can obtain an
1130
   *             anonymous logger through the static factory method
1131
   *             {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
1132
   */
1133
  public void setParent(Logger parent)
1134
  {
1135
    synchronized (lock)
1136
      {
1137
        if (parent == null)
1138
          throw new NullPointerException();
1139
 
1140
        if (this == root)
1141
          throw new IllegalArgumentException(
1142
                                             "the root logger can only have a null parent");
1143
 
1144
        /*
1145
         * An application is allowed to control an anonymous logger without
1146
         * having the permission to control the logging infrastructure.
1147
         */
1148
        if (! anonymous)
1149
          LogManager.getLogManager().checkAccess();
1150
 
1151
        this.parent = parent;
1152
      }
1153
  }
1154
 
1155
  /**
1156
   * Gets the StackTraceElement of the first class that is not this class. That
1157
   * should be the initial caller of a logging method.
1158
   *
1159
   * @return caller of the initial logging method or null if unknown.
1160
   */
1161
  private StackTraceElement getCallerStackFrame()
1162
  {
1163
    Throwable t = new Throwable();
1164
    StackTraceElement[] stackTrace = t.getStackTrace();
1165
    int index = 0;
1166
 
1167
    // skip to stackentries until this class
1168
    while (index < stackTrace.length
1169
           && ! stackTrace[index].getClassName().equals(getClass().getName()))
1170
      index++;
1171
 
1172
    // skip the stackentries of this class
1173
    while (index < stackTrace.length
1174
           && stackTrace[index].getClassName().equals(getClass().getName()))
1175
      index++;
1176
 
1177
    return index < stackTrace.length ? stackTrace[index] : null;
1178
  }
1179
 
1180
  /**
1181
   * Reset and close handlers attached to this logger. This function is package
1182
   * private because it must only be available to the LogManager.
1183
   */
1184
  void resetLogger()
1185
  {
1186
    for (int i = 0; i < handlers.length; i++)
1187
      {
1188
        handlers[i].close();
1189
        handlerList.remove(handlers[i]);
1190
      }
1191
    handlers = getHandlers();
1192
  }
1193
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.