Source Code Cross Referenced for LogManager.java in  » Apache-Harmony-Java-SE » java-package » java » util » logging » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » java package » java.util.logging 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* 
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        package java.util.logging;
019:
020:        import java.beans.PropertyChangeListener;
021:        import java.beans.PropertyChangeSupport;
022:        import java.io.BufferedInputStream;
023:        import java.io.File;
024:        import java.io.FileInputStream;
025:        import java.io.IOException;
026:        import java.io.InputStream;
027:        import java.lang.management.ManagementFactory;
028:        import java.lang.reflect.Method;
029:        import java.security.AccessController;
030:        import java.security.PrivilegedAction;
031:        import java.util.Collection;
032:        import java.util.Enumeration;
033:        import java.util.Hashtable;
034:        import java.util.Iterator;
035:        import java.util.Properties;
036:        import java.util.Set;
037:        import java.util.StringTokenizer;
038:
039:        import javax.management.MBeanServer;
040:        import javax.management.ObjectInstance;
041:        import javax.management.ObjectName;
042:
043:        import org.apache.harmony.logging.internal.nls.Messages;
044:
045:        /**
046:         * <code>LogManager</code> is used to manage named <code>Logger</code>s and
047:         * any shared logging properties.
048:         * <p>
049:         * There is one global <code>LogManager</code> instance in the application,
050:         * which can be obtained by calling the static method
051:         * <code>LogManager.getLogManager()</code>.
052:         * </p>
053:         * <p>
054:         * All methods on this type can be taken as being thread safe.
055:         * </p>
056:         * <p>
057:         * The <code>LogManager</code> class can be specified by the
058:         * "java.util.logging.manager" system property. If the property is unavailable
059:         * or invalid <code>java.util.logging.LogManager</code> will be used by
060:         * default.
061:         * </p>
062:         * <p>
063:         * On initialization, <code>LogManager</code> reads its configuration data
064:         * from a properties file, which by default is the "lib/logging.properties" file
065:         * in the JRE directory.
066:         * </p>
067:         * <p>
068:         * However, two system properties can be used instead to customize the
069:         * initialization of the <code>LogManager</code>:
070:         * <ul>
071:         * <li>"java.util.logging.config.class"</li>
072:         * <li>"java.util.logging.config.file"</li>
073:         * </ul>
074:         * </p>
075:         * <p>
076:         * These properties can be set either by using the Preferences API, as a command
077:         * line option or by passing the appropriate system property definitions to
078:         * JNI_CreateJavaVM.
079:         * </p>
080:         * <p>
081:         * The "java.util.logging.config.class" property should specify a class name. If
082:         * it is set, this class will be loaded and instantiated during
083:         * <code>LogManager</code>'s initialization, so that this object's default
084:         * constructor can read the initial configuration and define properties for the
085:         * <code>LogManager</code>.
086:         * </p>
087:         * <p>
088:         * The "java.util.logging.config.file" system property can be used to specify a
089:         * properties file if the "java.util.logging.config.class" property has not been
090:         * used. This file will be read instead of the default properties file.
091:         * </p>
092:         * <p>
093:         * Some global logging properties are as follows:
094:         * <ul>
095:         * <li>"handlers" - a list of handler classes, separated by whitespace. These
096:         * classes must be subclasses of <code>Handler</code> and must have a public
097:         * no-argument constructor. They will be registered with the root
098:         * <code>Logger</code>.</li>
099:         * <li>"config" - a list of configuration classes, separated by whitespace.
100:         * These classes should also have a public no-argument default constructor,
101:         * which should contain all the code for applying that configuration to the
102:         * logging system.
103:         * </ul>
104:         * </p>
105:         * <p>
106:         * Besides global properties, properties for individual <code>Loggers</code>
107:         * and <code>Handlers</code> can be specified in the property files. The names
108:         * of these properties will start with the fully qualified name of the handler
109:         * or logger.
110:         * </p>
111:         * <p>
112:         * The <code>LogManager</code> organizes <code>Loggers</code> based on their
113:         * fully qualified names. For example, "x.y.z" is child of "x.y".
114:         * </p>
115:         * <p>
116:         * Levels for <code>Loggers</code> can be defined by properties whose name end
117:         * with ".level". For example, "alogger.level = 4" sets the level for the logger
118:         * "alogger" to 4, Any children of "alogger" will also be given the level 4
119:         * unless specified lower down in the properties file. The property ".level"
120:         * will set the log level for the root logger.
121:         * </p>
122:         * 
123:         */
124:        public class LogManager {
125:            /*
126:             * ------------------------------------------------------------------- Class
127:             * variables
128:             * -------------------------------------------------------------------
129:             */
130:
131:            // The line separator of the underlying OS
132:            // Use privileged code to read the line.separator system property
133:            private static final String lineSeparator = getPrivilegedSystemProperty("line.separator"); //$NON-NLS-1$
134:
135:            // The shared logging permission
136:            private static final LoggingPermission perm = new LoggingPermission(
137:                    "control", null); //$NON-NLS-1$
138:
139:            // the singleton instance
140:            static LogManager manager;
141:
142:            /**
143:             * <p>
144:             * The String value of the {@link LoggingMXBean}'s ObjectName.
145:             * </p>
146:             */
147:            public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; //$NON-NLS-1$
148:
149:            /**
150:             * Get the <code>LoggingMXBean</code> instance
151:             * 
152:             * @return the <code>LoggingMXBean</code> instance
153:             */
154:            public static LoggingMXBean getLoggingMXBean() {
155:                try {
156:                    ObjectName loggingMXBeanName = new ObjectName(
157:                            LOGGING_MXBEAN_NAME);
158:                    MBeanServer platformBeanServer = ManagementFactory
159:                            .getPlatformMBeanServer();
160:                    Set loggingMXBeanSet = platformBeanServer.queryMBeans(
161:                            loggingMXBeanName, null);
162:
163:                    if (loggingMXBeanSet.size() != 1) {
164:                        // logging.21=There Can Be Only One logging MX bean.
165:                        throw new AssertionError(Messages
166:                                .getString("logging.21")); //$NON-NLS-1$
167:                    }
168:
169:                    Iterator i = loggingMXBeanSet.iterator();
170:                    ObjectInstance loggingMXBeanOI = (ObjectInstance) i.next();
171:                    String lmxbcn = loggingMXBeanOI.getClassName();
172:                    Class lmxbc = Class.forName(lmxbcn);
173:                    Method giMethod = lmxbc.getDeclaredMethod("getInstance"); //$NON-NLS-1$
174:                    giMethod.setAccessible(true);
175:                    LoggingMXBean lmxb = (LoggingMXBean) giMethod.invoke(null,
176:                            new Object[] {});
177:
178:                    return lmxb;
179:                } catch (Exception e) {
180:                    // TODO
181:                    // e.printStackTrace();
182:                }
183:                // logging.22=Exception occurred while getting the logging MX bean.
184:                throw new AssertionError(Messages.getString("logging.22")); //$NON-NLS-1$
185:            }
186:
187:            // FIXME: use weak reference to avoid heap memory leak
188:            private Hashtable<String, Logger> loggers;
189:
190:            // the configuration properties
191:            private Properties props;
192:
193:            // the property change listener
194:            private PropertyChangeSupport listeners;
195:
196:            static {
197:                // init LogManager singleton instance
198:                AccessController.doPrivileged(new PrivilegedAction<Object>() {
199:                    public Object run() {
200:                        String className = System
201:                                .getProperty("java.util.logging.manager"); //$NON-NLS-1$
202:
203:                        if (null != className) {
204:                            manager = (LogManager) getInstanceByClass(className);
205:                        }
206:                        if (null == manager) {
207:                            manager = new LogManager();
208:                        }
209:
210:                        // read configuration
211:                        try {
212:                            manager.readConfiguration();
213:                        } catch (Exception e) {
214:                            e.printStackTrace();
215:                        }
216:
217:                        // if global logger has been initialized, set root as its parent
218:                        Logger root = new Logger("", null); //$NON-NLS-1$
219:                        root.setLevel(Level.INFO);
220:                        Logger.global.setParent(root);
221:
222:                        manager.addLogger(root);
223:                        manager.addLogger(Logger.global);
224:                        return null;
225:                    }
226:                });
227:            }
228:
229:            /**
230:             * Default constructor. This is not public because there should be only one
231:             * <code>LogManager</code> instance, which can be get by
232:             * <code>LogManager.getLogManager(</code>. This is protected so that
233:             * application can subclass the object.
234:             */
235:            protected LogManager() {
236:                loggers = new Hashtable<String, Logger>();
237:                props = new Properties();
238:                listeners = new PropertyChangeSupport(this );
239:                // add shutdown hook to ensure that the associated resource will be
240:                // freed when JVM exits
241:                AccessController.doPrivileged(new PrivilegedAction<Void>() {
242:                    public Void run() {
243:                        Runtime.getRuntime().addShutdownHook(new Thread() {
244:                            @Override
245:                            public void run() {
246:                                reset();
247:                            }
248:                        });
249:                        return null;
250:                    }
251:                });
252:            }
253:
254:            /*
255:             * Package private utilities Returns the line separator of the underlying
256:             * OS.
257:             */
258:            static String getSystemLineSeparator() {
259:                return lineSeparator;
260:            }
261:
262:            /**
263:             * Check that the caller has <code>LoggingPermission("control")</code> so
264:             * that it is trusted to modify the configuration for logging framework. If
265:             * the check passes, just return, otherwise <code>SecurityException</code>
266:             * will be thrown.
267:             * 
268:             * @throws SecurityException
269:             *             if there is a security manager in operation and the invoker
270:             *             of this method does not have the required security permission
271:             *             <code>LoggingPermission("control")</code>
272:             */
273:            public void checkAccess() {
274:                if (null != System.getSecurityManager()) {
275:                    System.getSecurityManager().checkPermission(perm);
276:                }
277:            }
278:
279:            /**
280:             * Add a given logger into the hierarchical namespace. The
281:             * <code>Logger.addLogger()</code> factory methods call this method to add
282:             * newly created Logger. This returns false if a logger with the given name
283:             * has existed in the namespace
284:             * <p>
285:             * Note that the <code>LogManager</code> may only retain weak references
286:             * to registered loggers. In order to prevent <code>Logger</code> objects
287:             * from being unexpectedly garbage collected it is necessary for
288:             * <i>applications</i> to maintain references to them.
289:             * </p>
290:             * 
291:             * @param logger
292:             *            the logger to be added
293:             * @return true if the given logger is added into the namespace
294:             *         successfully, false if the logger of given name has existed in
295:             *         the namespace
296:             */
297:            public synchronized boolean addLogger(Logger logger) {
298:                String name = logger.getName();
299:                if (null != loggers.get(name)) {
300:                    return false;
301:                }
302:                addToFamilyTree(logger, name);
303:                loggers.put(name, logger);
304:                logger.setManager(this );
305:                return true;
306:            }
307:
308:            private void addToFamilyTree(Logger logger, String name) {
309:                Logger parent = null;
310:                // find parent
311:                int lastSeparator;
312:                String parentName = name;
313:                while ((lastSeparator = parentName.lastIndexOf('.')) != -1) {
314:                    parentName = parentName.substring(0, lastSeparator);
315:                    parent = loggers.get(parentName);
316:                    if (parent != null) {
317:                        logger.internalSetParent(parent);
318:                        break;
319:                    } else if (getProperty(parentName + ".level") != null || //$NON-NLS-1$
320:                            getProperty(parentName + ".handlers") != null) { //$NON-NLS-1$
321:                        parent = Logger.getLogger(parentName);
322:                        logger.internalSetParent(parent);
323:                        break;
324:                    }
325:                }
326:                if (parent == null && null != (parent = loggers.get(""))) { //$NON-NLS-1$
327:                    logger.internalSetParent(parent);
328:                }
329:
330:                // find children
331:                // TODO: performance can be improved here?
332:                Collection<Logger> allLoggers = loggers.values();
333:                for (final Logger child : allLoggers) {
334:                    Logger oldParent = child.getParent();
335:                    if (parent == oldParent
336:                            && (name.length() == 0 || child.getName()
337:                                    .startsWith(name + '.'))) {
338:                        final Logger this Logger = logger;
339:                        AccessController
340:                                .doPrivileged(new PrivilegedAction<Object>() {
341:                                    public Object run() {
342:                                        child.setParent(this Logger);
343:                                        return null;
344:                                    }
345:                                });
346:                        if (null != oldParent) {
347:                            // -- remove from old parent as the parent has been changed
348:                            oldParent.removeChild(child);
349:                        }
350:                    }
351:                }
352:            }
353:
354:            /**
355:             * Get the logger with the given name
356:             * 
357:             * @param name
358:             *            name of logger
359:             * @return logger with given name, or null if nothing is found
360:             */
361:            public synchronized Logger getLogger(String name) {
362:                return loggers.get(name);
363:            }
364:
365:            /**
366:             * Get a <code>Enumeration</code> of all registered logger names
367:             * 
368:             * @return enumeration of registered logger names
369:             */
370:            public synchronized Enumeration<String> getLoggerNames() {
371:                return loggers.keys();
372:            }
373:
374:            /**
375:             * Get the global <code>LogManager</code> instance
376:             * 
377:             * @return the global <code>LogManager</code> instance
378:             */
379:            public static LogManager getLogManager() {
380:                return manager;
381:            }
382:
383:            /**
384:             * Get the value of property with given name
385:             * 
386:             * @param name
387:             *            the name of property
388:             * @return the value of property
389:             */
390:            public String getProperty(String name) {
391:                return props.getProperty(name);
392:            }
393:
394:            /**
395:             * Re-initialize the properties and configuration. The initialization
396:             * process is same as the <code>LogManager</code> instantiation.
397:             * <p>
398:             * A <code>PropertyChangeEvent</code> must be fired.
399:             * </p>
400:             * 
401:             * @throws IOException
402:             *             if any IO related problems happened
403:             * @throws SecurityException
404:             *             if security manager exists and it determines that caller does
405:             *             not have the required permissions to perform this action
406:             */
407:            public void readConfiguration() throws IOException {
408:                checkAccess();
409:                // check config class
410:                String configClassName = System
411:                        .getProperty("java.util.logging.config.class"); //$NON-NLS-1$
412:                if (null == configClassName
413:                        || null == getInstanceByClass(configClassName)) {
414:                    // if config class failed, check config file
415:                    String configFile = System
416:                            .getProperty("java.util.logging.config.file"); //$NON-NLS-1$
417:
418:                    if (null == configFile) {
419:                        // if cannot find configFile, use default logging.properties
420:                        configFile = new StringBuilder()
421:                                .append(System.getProperty("java.home")).append(File.separator) //$NON-NLS-1$
422:                                .append("lib").append(File.separator).append( //$NON-NLS-1$
423:                                        "logging.properties").toString(); //$NON-NLS-1$
424:                    }
425:
426:                    InputStream input = null;
427:                    try {
428:                        input = new BufferedInputStream(new FileInputStream(
429:                                configFile));
430:                        readConfigurationImpl(input);
431:                    } finally {
432:                        if (input != null) {
433:                            try {
434:                                input.close();
435:                            } catch (Exception e) {// ignore
436:                            }
437:                        }
438:                    }
439:                }
440:            }
441:
442:            // use privilege code to get system property
443:            static String getPrivilegedSystemProperty(final String key) {
444:                return AccessController
445:                        .doPrivileged(new PrivilegedAction<String>() {
446:                            public String run() {
447:                                return System.getProperty(key);
448:                            }
449:                        });
450:            }
451:
452:            // use SystemClassLoader to load class from system classpath
453:            static Object getInstanceByClass(final String className) {
454:                try {
455:                    Class<?> clazz = ClassLoader.getSystemClassLoader()
456:                            .loadClass(className);
457:                    return clazz.newInstance();
458:                } catch (Exception e) {
459:                    try {
460:                        Class<?> clazz = Thread.currentThread()
461:                                .getContextClassLoader().loadClass(className);
462:                        return clazz.newInstance();
463:                    } catch (Exception innerE) {
464:                        // logging.20=Loading class "{0}" failed
465:                        System.err.println(Messages.getString(
466:                                "logging.20", className)); //$NON-NLS-1$
467:                        System.err.println(innerE);
468:                        return null;
469:                    }
470:                }
471:
472:            }
473:
474:            // actual initialization process from a given input stream
475:            private synchronized void readConfigurationImpl(InputStream ins)
476:                    throws IOException {
477:                reset();
478:                props.load(ins);
479:
480:                // parse property "config" and apply setting
481:                String configs = props.getProperty("config"); //$NON-NLS-1$
482:                if (null != configs) {
483:                    StringTokenizer st = new StringTokenizer(configs, " "); //$NON-NLS-1$
484:                    while (st.hasMoreTokens()) {
485:                        String configerName = st.nextToken();
486:                        getInstanceByClass(configerName);
487:                    }
488:                }
489:
490:                // set levels for logger
491:                Collection<Logger> allLoggers = loggers.values();
492:                for (Logger logger : allLoggers) {
493:                    String property = props.getProperty(logger.getName()
494:                            + ".level"); //$NON-NLS-1$
495:                    if (null != property) {
496:                        logger.setLevel(Level.parse(property));
497:                    }
498:                }
499:                listeners.firePropertyChange(null, null, null);
500:            }
501:
502:            /**
503:             * Re-initialize the properties and configuration from the given
504:             * <code>InputStream</code>
505:             * <p>
506:             * A <code>PropertyChangeEvent</code> must be fired.
507:             * </p>
508:             * 
509:             * @param ins
510:             *            the input stream.
511:             * @throws IOException
512:             *             if any IO related problems happened
513:             * @throws SecurityException
514:             *             if security manager exists and it determines that caller does
515:             *             not have the required permissions to perform this action
516:             */
517:            public void readConfiguration(InputStream ins) throws IOException {
518:                checkAccess();
519:                readConfigurationImpl(ins);
520:            }
521:
522:            /**
523:             * Reset configuration.
524:             * <p>
525:             * All handlers are closed and removed from any named loggers. All loggers'
526:             * level is set to null, except the root logger's level is set to
527:             * <code>Level.INFO</code>.
528:             * </p>
529:             * 
530:             * @throws SecurityException
531:             *             if security manager exists and it determines that caller does
532:             *             not have the required permissions to perform this action
533:             */
534:            public void reset() {
535:                checkAccess();
536:                props = new Properties();
537:                Enumeration<String> names = getLoggerNames();
538:                while (names.hasMoreElements()) {
539:                    String name = names.nextElement();
540:                    Logger logger = getLogger(name);
541:                    if (logger != null) {
542:                        logger.reset();
543:                    }
544:                }
545:                Logger root = loggers.get(""); //$NON-NLS-1$
546:                if (null != root) {
547:                    root.setLevel(Level.INFO);
548:                }
549:            }
550:
551:            /**
552:             * Add a <code>PropertyChangeListener</code>, which will be invoked when
553:             * the properties are reread.
554:             * 
555:             * @param l
556:             *            the <code>PropertyChangeListener</code> to be added
557:             * @throws SecurityException
558:             *             if security manager exists and it determines that caller does
559:             *             not have the required permissions to perform this action
560:             */
561:            public void addPropertyChangeListener(PropertyChangeListener l) {
562:                if (l == null) {
563:                    throw new NullPointerException();
564:                }
565:                checkAccess();
566:                listeners.addPropertyChangeListener(l);
567:            }
568:
569:            /**
570:             * Remove a <code>PropertyChangeListener</code>, do nothing if the given
571:             * listener is not found.
572:             * 
573:             * @param l
574:             *            the <code>PropertyChangeListener</code> to be removed
575:             * @throws SecurityException
576:             *             if security manager exists and it determines that caller does
577:             *             not have the required permissions to perform this action
578:             */
579:            public void removePropertyChangeListener(PropertyChangeListener l) {
580:                checkAccess();
581:                listeners.removePropertyChangeListener(l);
582:            }
583:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.