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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* LogManager.java -- a class for maintaining Loggers and managing
2
   configuration properties
3
   Copyright (C) 2002, 2005, 2006, 2007 Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
 
40
package java.util.logging;
41
 
42
import gnu.classpath.SystemProperties;
43
 
44
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeSupport;
46
import java.io.ByteArrayInputStream;
47
import java.io.IOException;
48
import java.io.InputStream;
49
import java.lang.ref.WeakReference;
50
import java.net.URL;
51
import java.util.Collections;
52
import java.util.Enumeration;
53
import java.util.HashMap;
54
import java.util.Iterator;
55
import java.util.List;
56
import java.util.Map;
57
import java.util.Properties;
58
import java.util.StringTokenizer;
59
 
60
/**
61
 * The <code>LogManager</code> maintains a hierarchical namespace
62
 * of Logger objects and manages properties for configuring the logging
63
 * framework. There exists only one single <code>LogManager</code>
64
 * per virtual machine. This instance can be retrieved using the
65
 * static method {@link #getLogManager()}.
66
 *
67
 * <p><strong>Configuration Process:</strong> The global LogManager
68
 * object is created and configured when the class
69
 * <code>java.util.logging.LogManager</code> is initialized.
70
 * The configuration process includes the subsequent steps:
71
 *
72
 * <ul>
73
 * <li>If the system property <code>java.util.logging.manager</code>
74
 *     is set to the name of a subclass of
75
 *     <code>java.util.logging.LogManager</code>, an instance of
76
 *     that subclass is created and becomes the global LogManager.
77
 *     Otherwise, a new instance of LogManager is created.</li>
78
 * <li>The <code>LogManager</code> constructor tries to create
79
 *     a new instance of the class specified by the system
80
 *     property <code>java.util.logging.config.class</code>.
81
 *     Typically, the constructor of this class will call
82
 *     <code>LogManager.getLogManager().readConfiguration(java.io.InputStream)</code>
83
 *     for configuring the logging framework.
84
 *     The configuration process stops at this point if
85
 *     the system property <code>java.util.logging.config.class</code>
86
 *     is set (irrespective of whether the class constructor
87
 *     could be called or an exception was thrown).</li>
88
 *
89
 * <li>If the system property <code>java.util.logging.config.class</code>
90
 *     is <em>not</em> set, the configuration parameters are read in from
91
 *     a file and passed to
92
 *     {@link #readConfiguration(java.io.InputStream)}.
93
 *     The name and location of this file are specified by the system
94
 *     property <code>java.util.logging.config.file</code>.</li>
95
 * <li>If the system property <code>java.util.logging.config.file</code>
96
 *     is not set, however, the contents of the URL
97
 *     "{gnu.classpath.home.url}/logging.properties" are passed to
98
 *     {@link #readConfiguration(java.io.InputStream)}.
99
 *     Here, "{gnu.classpath.home.url}" stands for the value of
100
 *     the system property <code>gnu.classpath.home.url</code>.</li>
101
 * </ul>
102
 *
103
 * <p>The <code>LogManager</code> has a level of <code>INFO</code> by
104
 * default, and this will be inherited by <code>Logger</code>s unless they
105
 * override it either by properties or programmatically.
106
 *
107
 * @author Sascha Brawer (brawer@acm.org)
108
 */
109
public class LogManager
110
{
111
  /**
112
   * The object name for the logging management bean.
113
   * @since 1.5
114
   */
115
  public static final String LOGGING_MXBEAN_NAME
116
    = "java.util.logging:type=Logging";
117
 
118
  /**
119
   * The singleton LogManager instance.
120
   */
121
  private static LogManager logManager;
122
 
123
  /**
124
   * The singleton logging bean.
125
   */
126
  private static LoggingMXBean loggingBean;
127
 
128
  /**
129
   * The registered named loggers; maps the name of a Logger to
130
   * a WeakReference to it.
131
   */
132
  private Map<String, WeakReference<Logger>> loggers;
133
 
134
  /**
135
   * The properties for the logging framework which have been
136
   * read in last.
137
   */
138
  private Properties properties;
139
 
140
  /**
141
   * A delegate object that provides support for handling
142
   * PropertyChangeEvents.  The API specification does not
143
   * mention which bean should be the source in the distributed
144
   * PropertyChangeEvents, but Mauve test code has determined that
145
   * the Sun J2SE 1.4 reference implementation uses the LogManager
146
   * class object. This is somewhat strange, as the class object
147
   * is not the bean with which listeners have to register, but
148
   * there is no reason for the GNU Classpath implementation to
149
   * behave differently from the reference implementation in
150
   * this case.
151
   */
152
  private final PropertyChangeSupport pcs = new PropertyChangeSupport( /* source bean */
153
                                                                      LogManager.class);
154
 
155
  protected LogManager()
156
  {
157
    loggers = new HashMap();
158
  }
159
 
160
  /**
161
   * Returns the globally shared LogManager instance.
162
   */
163
  public static synchronized LogManager getLogManager()
164
  {
165
    if (logManager == null)
166
      {
167
        logManager = makeLogManager();
168
        initLogManager();
169
      }
170
    return logManager;
171
  }
172
 
173
  private static final String MANAGER_PROPERTY = "java.util.logging.manager";
174
 
175
  private static LogManager makeLogManager()
176
  {
177
    String managerClassName = SystemProperties.getProperty(MANAGER_PROPERTY);
178
    LogManager manager = (LogManager) createInstance
179
      (managerClassName, LogManager.class, MANAGER_PROPERTY);
180
    if (manager == null)
181
      manager = new LogManager();
182
    return manager;
183
  }
184
 
185
  private static final String CONFIG_PROPERTY = "java.util.logging.config.class";
186
 
187
  private static void initLogManager()
188
  {
189
    LogManager manager = getLogManager();
190
    Logger.root.setLevel(Level.INFO);
191
    manager.addLogger(Logger.root);
192
 
193
    /* The Javadoc description of the class explains
194
     * what is going on here.
195
     */
196
    Object configurator = createInstance(System.getProperty(CONFIG_PROPERTY),
197
                                         /* must be instance of */ Object.class,
198
                                         CONFIG_PROPERTY);
199
 
200
    try
201
      {
202
        if (configurator == null)
203
          manager.readConfiguration();
204
      }
205
    catch (IOException ex)
206
      {
207
        /* FIXME: Is it ok to ignore exceptions here? */
208
      }
209
  }
210
 
211
  /**
212
   * Registers a listener which will be notified when the
213
   * logging properties are re-read.
214
   */
215
  public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
216
  {
217
    /* do not register null. */
218
    listener.getClass();
219
 
220
    pcs.addPropertyChangeListener(listener);
221
  }
222
 
223
  /**
224
   * Unregisters a listener.
225
   *
226
   * If <code>listener</code> has not been registered previously,
227
   * nothing happens.  Also, no exception is thrown if
228
   * <code>listener</code> is <code>null</code>.
229
   */
230
  public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
231
  {
232
    if (listener != null)
233
      pcs.removePropertyChangeListener(listener);
234
  }
235
 
236
  /**
237
   * Adds a named logger.  If a logger with the same name has
238
   * already been registered, the method returns <code>false</code>
239
   * without adding the logger.
240
   *
241
   * <p>The <code>LogManager</code> only keeps weak references
242
   * to registered loggers.  Therefore, names can become available
243
   * after automatic garbage collection.
244
   *
245
   * @param logger the logger to be added.
246
   *
247
   * @return <code>true</code>if <code>logger</code> was added,
248
   *         <code>false</code> otherwise.
249
   *
250
   * @throws NullPointerException if <code>name</code> is
251
   *         <code>null</code>.
252
   */
253
  public synchronized boolean addLogger(Logger logger)
254
  {
255
    /* To developers thinking about to remove the 'synchronized'
256
     * declaration from this method: Please read the comment
257
     * in java.util.logging.Logger.getLogger(String, String)
258
     * and make sure that whatever you change wrt. synchronization
259
     * does not endanger thread-safety of Logger.getLogger.
260
     * The current implementation of Logger.getLogger assumes
261
     * that LogManager does its synchronization on the globally
262
     * shared instance of LogManager.
263
     */
264
    String name;
265
    WeakReference ref;
266
 
267
    /* This will throw a NullPointerException if logger is null,
268
     * as required by the API specification.
269
     */
270
    name = logger.getName();
271
 
272
    ref = loggers.get(name);
273
    if (ref != null)
274
      {
275
        if (ref.get() != null)
276
          return false;
277
 
278
        /* There has been a logger under this name in the past,
279
         * but it has been garbage collected.
280
         */
281
        loggers.remove(ref);
282
      }
283
 
284
    /* Adding a named logger requires a security permission. */
285
    if ((name != null) && ! name.equals(""))
286
      checkAccess();
287
 
288
    Logger parent = findAncestor(logger);
289
    loggers.put(name, new WeakReference<Logger>(logger));
290
    if (parent != logger.getParent())
291
      logger.setParent(parent);
292
 
293
    // The level of the newly added logger must be specified.
294
    // The easiest case is if there is a level for exactly this logger
295
    // in the properties. If no such level exists the level needs to be
296
    // searched along the hirachy. So if there is a new logger 'foo.blah.blub'
297
    // and an existing parent logger 'foo' the properties 'foo.blah.blub.level'
298
    // and 'foo.blah.level' need to be checked. If both do not exist in the
299
    // properties the level of the new logger is set to 'null' (i.e. it uses the
300
    // level of its parent 'foo').
301
    Level logLevel = logger.getLevel();
302
    String searchName = name;
303
    String parentName = parent != null ? parent.getName() : "";
304
    while (logLevel == null && ! searchName.equals(parentName))
305
      {
306
        logLevel = getLevelProperty(searchName + ".level", logLevel);
307
        int index = searchName.lastIndexOf('.');
308
        if(index > -1)
309
          searchName = searchName.substring(0,index);
310
        else
311
          searchName = "";
312
      }
313
    logger.setLevel(logLevel);
314
 
315
    /* It can happen that existing loggers should be children of
316
     * the newly added logger. For example, assume that there
317
     * already exist loggers under the names "", "foo", and "foo.bar.baz".
318
     * When adding "foo.bar", the logger "foo.bar.baz" should change
319
     * its parent to "foo.bar".
320
     */
321
    for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
322
      {
323
        Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next()))
324
          .get();
325
        if ((possChild == null) || (possChild == logger)
326
            || (possChild.getParent() != parent))
327
          continue;
328
 
329
        if (! possChild.getName().startsWith(name))
330
          continue;
331
 
332
        if (possChild.getName().charAt(name.length()) != '.')
333
          continue;
334
 
335
        possChild.setParent(logger);
336
      }
337
 
338
    return true;
339
  }
340
 
341
  /**
342
   * Finds the closest ancestor for a logger among the currently
343
   * registered ones.  For example, if the currently registered
344
   * loggers have the names "", "foo", and "foo.bar", the result for
345
   * "foo.bar.baz" will be the logger whose name is "foo.bar".
346
   *
347
   * @param child a logger for whose name no logger has been
348
   *        registered.
349
   *
350
   * @return the closest ancestor for <code>child</code>,
351
   *         or <code>null</code> if <code>child</code>
352
   *         is the root logger.
353
   *
354
   * @throws NullPointerException if <code>child</code>
355
   *         is <code>null</code>.
356
   */
357
  private synchronized Logger findAncestor(Logger child)
358
  {
359
    String childName = child.getName();
360
    int childNameLength = childName.length();
361
    Logger best = Logger.root;
362
    int bestNameLength = 0;
363
 
364
    Logger cand;
365
    int candNameLength;
366
 
367
    if (child == Logger.root)
368
      return null;
369
 
370
    for (String candName : loggers.keySet())
371
      {
372
        candNameLength = candName.length();
373
 
374
        if (candNameLength > bestNameLength
375
            && childNameLength > candNameLength
376
            && childName.startsWith(candName)
377
            && childName.charAt(candNameLength) == '.')
378
          {
379
            cand = loggers.get(candName).get();
380
            if ((cand == null) || (cand == child))
381
              continue;
382
 
383
            bestNameLength = candName.length();
384
            best = cand;
385
          }
386
      }
387
 
388
    return best;
389
  }
390
 
391
  /**
392
   * Returns a Logger given its name.
393
   *
394
   * @param name the name of the logger.
395
   *
396
   * @return a named Logger, or <code>null</code> if there is no
397
   *     logger with that name.
398
   *
399
   * @throw java.lang.NullPointerException if <code>name</code>
400
   *     is <code>null</code>.
401
   */
402
  public synchronized Logger getLogger(String name)
403
  {
404
    WeakReference<Logger> ref;
405
 
406
    /* Throw a NullPointerException if name is null. */
407
    name.getClass();
408
 
409
    ref = loggers.get(name);
410
    if (ref != null)
411
      return ref.get();
412
    else
413
      return null;
414
  }
415
 
416
  /**
417
   * Returns an Enumeration of currently registered Logger names.
418
   * Since other threads can register loggers at any time, the
419
   * result could be different any time this method is called.
420
   *
421
   * @return an Enumeration with the names of the currently
422
   *    registered Loggers.
423
   */
424
  public synchronized Enumeration<String> getLoggerNames()
425
  {
426
    return Collections.enumeration(loggers.keySet());
427
  }
428
 
429
  /**
430
   * Resets the logging configuration by removing all handlers for
431
   * registered named loggers and setting their level to <code>null</code>.
432
   * The level of the root logger will be set to <code>Level.INFO</code>.
433
   *
434
   * @throws SecurityException if a security manager exists and
435
   *         the caller is not granted the permission to control
436
   *         the logging infrastructure.
437
   */
438
  public synchronized void reset() throws SecurityException
439
  {
440
    /* Throw a SecurityException if the caller does not have the
441
     * permission to control the logging infrastructure.
442
     */
443
    checkAccess();
444
 
445
    properties = new Properties();
446
 
447
    Iterator<WeakReference<Logger>> iter = loggers.values().iterator();
448
    while (iter.hasNext())
449
      {
450
        WeakReference<Logger> ref;
451
        Logger logger;
452
 
453
        ref = iter.next();
454
        if (ref != null)
455
          {
456
            logger = ref.get();
457
 
458
            if (logger == null)
459
              iter.remove();
460
            else if (logger != Logger.root)
461
              {
462
                logger.resetLogger();
463
                logger.setLevel(null);
464
              }
465
          }
466
      }
467
 
468
    Logger.root.setLevel(Level.INFO);
469
    Logger.root.resetLogger();
470
  }
471
 
472
  /**
473
   * Configures the logging framework by reading a configuration file.
474
   * The name and location of this file are specified by the system
475
   * property <code>java.util.logging.config.file</code>.  If this
476
   * property is not set, the URL
477
   * "{gnu.classpath.home.url}/logging.properties" is taken, where
478
   * "{gnu.classpath.home.url}" stands for the value of the system
479
   * property <code>gnu.classpath.home.url</code>.
480
   *
481
   * <p>The task of configuring the framework is then delegated to
482
   * {@link #readConfiguration(java.io.InputStream)}, which will
483
   * notify registered listeners after having read the properties.
484
   *
485
   * @throws SecurityException if a security manager exists and
486
   *         the caller is not granted the permission to control
487
   *         the logging infrastructure, or if the caller is
488
   *         not granted the permission to read the configuration
489
   *         file.
490
   *
491
   * @throws IOException if there is a problem reading in the
492
   *         configuration file.
493
   */
494
  public synchronized void readConfiguration()
495
    throws IOException, SecurityException
496
  {
497
    String path;
498
    InputStream inputStream;
499
 
500
    path = System.getProperty("java.util.logging.config.file");
501
    if ((path == null) || (path.length() == 0))
502
      {
503
        String url = (System.getProperty("gnu.classpath.home.url")
504
                      + "/logging.properties");
505
        try
506
          {
507
            inputStream = new URL(url).openStream();
508
          }
509
        catch (Exception e)
510
          {
511
            inputStream=null;
512
          }
513
 
514
        // If no config file could be found use a default configuration.
515
        if(inputStream == null)
516
          {
517
            String defaultConfig = "handlers = java.util.logging.ConsoleHandler   \n"
518
              + ".level=INFO \n";
519
            inputStream = new ByteArrayInputStream(defaultConfig.getBytes());
520
          }
521
      }
522
    else
523
      inputStream = new java.io.FileInputStream(path);
524
 
525
    try
526
      {
527
        readConfiguration(inputStream);
528
      }
529
    finally
530
      {
531
        // Close the stream in order to save
532
        // resources such as file descriptors.
533
        inputStream.close();
534
      }
535
  }
536
 
537
  public synchronized void readConfiguration(InputStream inputStream)
538
    throws IOException, SecurityException
539
  {
540
    Properties newProperties;
541
    Enumeration keys;
542
 
543
    checkAccess();
544
    newProperties = new Properties();
545
    newProperties.load(inputStream);
546
    reset();
547
    this.properties = newProperties;
548
    keys = newProperties.propertyNames();
549
 
550
    while (keys.hasMoreElements())
551
      {
552
        String key = ((String) keys.nextElement()).trim();
553
        String value = newProperties.getProperty(key);
554
 
555
        if (value == null)
556
          continue;
557
 
558
        value = value.trim();
559
 
560
        if ("handlers".equals(key))
561
          {
562
            // In Java 5 and earlier this was specified to be
563
            // whitespace-separated, but in reality it also accepted
564
            // commas (tomcat relied on this), and in Java 6 the
565
            // documentation was updated to fit the implementation.
566
            StringTokenizer tokenizer = new StringTokenizer(value,
567
                                                            " \t\n\r\f,");
568
            while (tokenizer.hasMoreTokens())
569
              {
570
                String handlerName = tokenizer.nextToken();
571
                Handler handler = (Handler)
572
                  createInstance(handlerName, Handler.class, key);
573
                // Tomcat also relies on the implementation ignoring
574
                // items in 'handlers' which are not class names.
575
                if (handler != null)
576
                  Logger.root.addHandler(handler);
577
              }
578
          }
579
 
580
        if (key.endsWith(".level"))
581
          {
582
            String loggerName = key.substring(0, key.length() - 6);
583
            Logger logger = getLogger(loggerName);
584
 
585
            if (logger == null)
586
              {
587
                logger = Logger.getLogger(loggerName);
588
                addLogger(logger);
589
              }
590
            Level level = null;
591
            try
592
              {
593
                level = Level.parse(value);
594
              }
595
            catch (IllegalArgumentException e)
596
              {
597
                warn("bad level \'" + value + "\'", e);
598
              }
599
            if (level != null)
600
              {
601
                logger.setLevel(level);
602
              }
603
            continue;
604
          }
605
      }
606
 
607
    /* The API specification does not talk about the
608
     * property name that is distributed with the
609
     * PropertyChangeEvent.  With test code, it could
610
     * be determined that the Sun J2SE 1.4 reference
611
     * implementation uses null for the property name.
612
     */
613
    pcs.firePropertyChange(null, null, null);
614
  }
615
 
616
  /**
617
   * Returns the value of a configuration property as a String.
618
   */
619
  public synchronized String getProperty(String name)
620
  {
621
    if (properties != null)
622
      return properties.getProperty(name);
623
    else
624
      return null;
625
  }
626
 
627
  /**
628
   * Returns the value of a configuration property as an integer.
629
   * This function is a helper used by the Classpath implementation
630
   * of java.util.logging, it is <em>not</em> specified in the
631
   * logging API.
632
   *
633
   * @param name the name of the configuration property.
634
   *
635
   * @param defaultValue the value that will be returned if the
636
   *        property is not defined, or if its value is not an integer
637
   *        number.
638
   */
639
  static int getIntProperty(String name, int defaultValue)
640
  {
641
    try
642
      {
643
        return Integer.parseInt(getLogManager().getProperty(name));
644
      }
645
    catch (Exception ex)
646
      {
647
        return defaultValue;
648
      }
649
  }
650
 
651
  /**
652
   * Returns the value of a configuration property as an integer,
653
   * provided it is inside the acceptable range.
654
   * This function is a helper used by the Classpath implementation
655
   * of java.util.logging, it is <em>not</em> specified in the
656
   * logging API.
657
   *
658
   * @param name the name of the configuration property.
659
   *
660
   * @param minValue the lowest acceptable value.
661
   *
662
   * @param maxValue the highest acceptable value.
663
   *
664
   * @param defaultValue the value that will be returned if the
665
   *        property is not defined, or if its value is not an integer
666
   *        number, or if it is less than the minimum value,
667
   *        or if it is greater than the maximum value.
668
   */
669
  static int getIntPropertyClamped(String name, int defaultValue,
670
                                   int minValue, int maxValue)
671
  {
672
    int val = getIntProperty(name, defaultValue);
673
    if ((val < minValue) || (val > maxValue))
674
      val = defaultValue;
675
    return val;
676
  }
677
 
678
  /**
679
   * Returns the value of a configuration property as a boolean.
680
   * This function is a helper used by the Classpath implementation
681
   * of java.util.logging, it is <em>not</em> specified in the
682
   * logging API.
683
   *
684
   * @param name the name of the configuration property.
685
   *
686
   * @param defaultValue the value that will be returned if the
687
   *        property is not defined, or if its value is neither
688
   *        <code>"true"</code> nor <code>"false"</code>.
689
   */
690
  static boolean getBooleanProperty(String name, boolean defaultValue)
691
  {
692
    try
693
      {
694
        return (Boolean.valueOf(getLogManager().getProperty(name))).booleanValue();
695
      }
696
    catch (Exception ex)
697
      {
698
        return defaultValue;
699
      }
700
  }
701
 
702
  /**
703
   * Returns the value of a configuration property as a Level.
704
   * This function is a helper used by the Classpath implementation
705
   * of java.util.logging, it is <em>not</em> specified in the
706
   * logging API.
707
   *
708
   * @param propertyName the name of the configuration property.
709
   *
710
   * @param defaultValue the value that will be returned if the
711
   *        property is not defined, or if
712
   *        {@link Level#parse(java.lang.String)} does not like
713
   *        the property value.
714
   */
715
  static Level getLevelProperty(String propertyName, Level defaultValue)
716
  {
717
    try
718
      {
719
        String value = getLogManager().getProperty(propertyName);
720
        if (value != null)
721
          return Level.parse(getLogManager().getProperty(propertyName));
722
        else
723
           return defaultValue;
724
      }
725
    catch (Exception ex)
726
      {
727
        return defaultValue;
728
      }
729
  }
730
 
731
  /**
732
   * Returns the value of a configuration property as a Class.
733
   * This function is a helper used by the Classpath implementation
734
   * of java.util.logging, it is <em>not</em> specified in the
735
   * logging API.
736
   *
737
   * @param propertyName the name of the configuration property.
738
   *
739
   * @param defaultValue the value that will be returned if the
740
   *        property is not defined, or if it does not specify
741
   *        the name of a loadable class.
742
   */
743
  static final Class getClassProperty(String propertyName, Class defaultValue)
744
  {
745
    String propertyValue = logManager.getProperty(propertyName);
746
 
747
    if (propertyValue != null)
748
      try
749
        {
750
          return locateClass(propertyValue);
751
        }
752
      catch (ClassNotFoundException e)
753
        {
754
          warn(propertyName + " = " + propertyValue, e);
755
        }
756
 
757
    return defaultValue;
758
  }
759
 
760
  static final Object getInstanceProperty(String propertyName, Class ofClass,
761
                                          Class defaultClass)
762
  {
763
    Class klass = getClassProperty(propertyName, defaultClass);
764
    if (klass == null)
765
      return null;
766
 
767
    try
768
      {
769
        Object obj = klass.newInstance();
770
        if (ofClass.isInstance(obj))
771
          return obj;
772
      }
773
    catch (InstantiationException e)
774
      {
775
        warn(propertyName + " = " + klass.getName(), e);
776
      }
777
    catch (IllegalAccessException e)
778
      {
779
        warn(propertyName + " = " + klass.getName(), e);
780
      }
781
 
782
    if (defaultClass == null)
783
      return null;
784
 
785
    try
786
      {
787
        return defaultClass.newInstance();
788
      }
789
    catch (java.lang.InstantiationException ex)
790
      {
791
        throw new RuntimeException(ex.getMessage());
792
      }
793
    catch (java.lang.IllegalAccessException ex)
794
      {
795
        throw new RuntimeException(ex.getMessage());
796
      }
797
  }
798
 
799
  /**
800
   * An instance of <code>LoggingPermission("control")</code>
801
   * that is shared between calls to <code>checkAccess()</code>.
802
   */
803
  private static final LoggingPermission controlPermission = new LoggingPermission("control",
804
                                                                                   null);
805
 
806
  /**
807
   * Checks whether the current security context allows changing
808
   * the configuration of the logging framework.  For the security
809
   * context to be trusted, it has to be granted
810
   * a LoggingPermission("control").
811
   *
812
   * @throws SecurityException if a security manager exists and
813
   *         the caller is not granted the permission to control
814
   *         the logging infrastructure.
815
   */
816
  public void checkAccess() throws SecurityException
817
  {
818
    SecurityManager sm = System.getSecurityManager();
819
    if (sm != null)
820
      sm.checkPermission(controlPermission);
821
  }
822
 
823
  /**
824
   * Creates a new instance of a class specified by name and verifies
825
   * that it is an instance (or subclass of) a given type.
826
   *
827
   * @param className the name of the class of which a new instance
828
   *        should be created.
829
   *
830
   * @param type the object created must be an instance of
831
   * <code>type</code> or any subclass of <code>type</code>
832
   *
833
   * @param property the system property to reference in error
834
   * messages
835
   *
836
   * @return the new instance, or <code>null</code> if
837
   *         <code>className</code> is <code>null</code>, if no class
838
   *         with that name could be found, if there was an error
839
   *         loading that class, or if the constructor of the class
840
   *         has thrown an exception.
841
   */
842
  private static final Object createInstance(String className, Class type,
843
                                             String property)
844
  {
845
    Class klass = null;
846
 
847
    if ((className == null) || (className.length() == 0))
848
      return null;
849
 
850
    try
851
      {
852
        klass = locateClass(className);
853
        if (type.isAssignableFrom(klass))
854
          return klass.newInstance();
855
        warn(property, className, "not an instance of " + type.getName());
856
      }
857
    catch (ClassNotFoundException e)
858
      {
859
        warn(property, className, "class not found", e);
860
      }
861
    catch (IllegalAccessException e)
862
      {
863
        warn(property, className, "illegal access", e);
864
      }
865
    catch (InstantiationException e)
866
      {
867
        warn(property, className, e);
868
      }
869
    catch (java.lang.LinkageError e)
870
      {
871
        warn(property, className, "linkage error", e);
872
      }
873
 
874
    return null;
875
  }
876
 
877
  private static final void warn(String property, String klass, Throwable t)
878
  {
879
    warn(property, klass, null, t);
880
  }
881
 
882
  private static final void warn(String property, String klass, String msg)
883
  {
884
    warn(property, klass, msg, null);
885
  }
886
 
887
  private static final void warn(String property, String klass, String msg,
888
                                 Throwable t)
889
  {
890
    warn("error instantiating '" + klass + "' referenced by " + property +
891
         (msg == null ? "" : ", " + msg), t);
892
  }
893
 
894
  /**
895
   * All debug warnings go through this method.
896
   */
897
 
898
  private static final void warn(String msg, Throwable t)
899
  {
900
    System.err.println("WARNING: " + msg);
901
    if (t != null)
902
      t.printStackTrace(System.err);
903
  }
904
 
905
  /**
906
   * Locates a class by first checking the system class loader and
907
   * then checking the context class loader.
908
   *
909
   * @param name the fully qualified name of the Class to locate
910
   * @return Class the located Class
911
   */
912
 
913
  private static Class locateClass(String name) throws ClassNotFoundException
914
  {
915
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
916
    try
917
      {
918
        return Class.forName(name, true, loader);
919
      }
920
    catch (ClassNotFoundException e)
921
      {
922
        loader = ClassLoader.getSystemClassLoader();
923
        return Class.forName(name, true, loader);
924
      }
925
  }
926
 
927
  /**
928
   * Return the logging bean.  There is a single logging bean per
929
   * VM instance.
930
   * @since 1.5
931
   */
932
  public static synchronized LoggingMXBean getLoggingMXBean()
933
  {
934
    if (loggingBean == null)
935
      {
936
        loggingBean = new LoggingMXBean()
937
        {
938
          public String getLoggerLevel(String logger)
939
          {
940
            LogManager mgr = getLogManager();
941
            Logger l = mgr.getLogger(logger);
942
            if (l == null)
943
              return null;
944
            Level lev = l.getLevel();
945
            if (lev == null)
946
              return "";
947
            return lev.getName();
948
          }
949
 
950
          public List getLoggerNames()
951
          {
952
            LogManager mgr = getLogManager();
953
            // This is inefficient, but perhaps better for maintenance.
954
            return Collections.list(mgr.getLoggerNames());
955
          }
956
 
957
          public String getParentLoggerName(String logger)
958
          {
959
            LogManager mgr = getLogManager();
960
            Logger l = mgr.getLogger(logger);
961
            if (l == null)
962
              return null;
963
            l = l.getParent();
964
            if (l == null)
965
              return "";
966
            return l.getName();
967
          }
968
 
969
          public void setLoggerLevel(String logger, String level)
970
          {
971
            LogManager mgr = getLogManager();
972
            Logger l = mgr.getLogger(logger);
973
            if (l == null)
974
              throw new IllegalArgumentException("no logger named " + logger);
975
            Level newLevel;
976
            if (level == null)
977
              newLevel = null;
978
            else
979
              newLevel = Level.parse(level);
980
            l.setLevel(newLevel);
981
          }
982
        };
983
      }
984
    return loggingBean;
985
  }
986
}

powered by: WebSVN 2.1.0

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