View Javadoc

1   package org.springframework.roo.support.logging;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.logging.ConsoleHandler;
6   import java.util.logging.Formatter;
7   import java.util.logging.Handler;
8   import java.util.logging.Level;
9   import java.util.logging.LogRecord;
10  import java.util.logging.Logger;
11  
12  import org.springframework.roo.support.util.Assert;
13  
14  /**
15   * Utility methods for dealing with {@link Handler} objects.
16   * 
17   * @author Ben Alex
18   * @since 1.0
19   *
20   */
21  public abstract class HandlerUtils {
22  	
23  	/**
24  	 * Obtains a {@link Logger} that guarantees to set the {@link Level}
25  	 * to {@link Level#FINE} if it is part of org.springframework.roo.
26  	 * Unfortunately this is needed due to a regression in JDK 1.6.0_18
27  	 * as per issue ROO-539.
28  	 * 
29  	 * @param clazz to retrieve the logger for (required)
30  	 * @return the logger, which will at least of {@link Level#FINE} if no level was specified
31  	 */
32  	public static final Logger getLogger(Class<?> clazz) {
33  		Assert.notNull(clazz, "Class required");
34  		Logger logger = Logger.getLogger(clazz.getName());
35  		if (logger.getLevel() == null && clazz.getName().startsWith("org.springframework.roo")) {
36  			logger.setLevel(Level.FINE);
37  		}
38  		return logger;
39  	}
40  	
41  	/**
42  	 * Replaces each {@link Handler} defined against the presented {@link Logger} with {@link DeferredLogHandler}.
43  	 * 
44  	 * <p>
45  	 * This is useful for ensuring any {@link Handler} defaults defined by the user are preserved and treated as the
46  	 * {@link DeferredLogHandler} "fallback" {@link Handler} if the indicated severity {@link Level} is encountered.
47  	 * 
48  	 * <p>
49  	 * This method will create a {@link ConsoleHandler} if the presented {@link Logger} has no current {@link Handler}.
50  	 * 
51  	 * @param logger to introspect and replace the {@link Handler}s for (required)
52  	 * @param fallbackSeverity to trigger fallback mode (required)
53  	 * @return the number of {@link DeferredLogHandler}s now registered against the {@link Logger} (guaranteed to be 1 or above)
54  	 */
55  	public static final int wrapWithDeferredLogHandler(Logger logger, Level fallbackSeverity) {
56  		Assert.notNull(logger, "Logger is required");
57  		Assert.notNull(fallbackSeverity, "Fallback severity is required");
58  		
59  		List<DeferredLogHandler> newHandlers = new ArrayList<DeferredLogHandler>();
60  		
61  		// Create DeferredLogHandlers for each Handler in presented Logger 
62  		Handler[] handlers = logger.getHandlers();
63  		if (handlers != null && handlers.length > 0) {
64  			for (Handler h : handlers) {
65  				logger.removeHandler(h);
66  				newHandlers.add(new DeferredLogHandler(h, fallbackSeverity));
67  			}
68  		}
69  		
70  		// Create a default DeferredLogHandler if no Handler was defined in the presented Logger
71  		if (newHandlers.size() == 0) {
72  			ConsoleHandler consoleHandler = new ConsoleHandler();
73  			consoleHandler.setFormatter(new Formatter() {
74  				public String format(LogRecord record) {
75  					return record.getMessage() + System.getProperty("line.separator");
76  				}
77  			});
78  			newHandlers.add(new DeferredLogHandler(consoleHandler, fallbackSeverity));
79  		}
80  
81  		// Add the new DeferredLogHandlers to the presented Logger
82  		for (DeferredLogHandler h : newHandlers) {
83  			logger.addHandler(h);
84  		}
85  		
86  		return newHandlers.size();
87  	}
88  	
89  	/**
90  	 * Registers the presented target {@link Handler} against any {@link DeferredLogHandler} encountered in the presented
91  	 * {@link Logger}.
92  	 * 
93  	 * <p>
94  	 * Generally this method is used on {@link Logger} instances that have previously been presented to the
95  	 * {@link #wrapWithDeferredLogHandler(Logger, Level)} method.
96  	 * 
97  	 * <p>
98  	 * The method will return a count of how many {@link DeferredLogHandler} instances it detected. Note that no
99  	 * attempt is made to distinguish between instances already possessing the intended target {@link Handler}
100 	 * or those already possessing any target {@link Handler} at all. This method always overwrites the target
101 	 * {@link Handler} and the returned count represents how many overwrites took place.
102 	 * 
103 	 * @param logger to introspect for {@link DeferredLogHandler} instances (required)
104 	 * @param target to set as the target {@link 
105 	 * @return number of {@link DeferredLogHandler} instances detected and updated (may be 0 if none found)
106 	 */
107 	public static final int registerTargetHandler(Logger logger, Handler target) {
108 		Assert.notNull(logger, "Logger is required");
109 		Assert.notNull(target, "Target handler is required");
110 		
111 		int replaced = 0;
112 		
113 		Handler[] handlers = logger.getHandlers();
114 		if (handlers != null && handlers.length > 0) {
115 			for (Handler h : handlers) {
116 				if (h instanceof DeferredLogHandler) {
117 					replaced++;
118 					DeferredLogHandler defLogger = (DeferredLogHandler) h;
119 					defLogger.setTargetHandler(target);
120 				}
121 			}
122 		}
123 
124 		return replaced;
125 	}
126 	
127 	/**
128 	 * Forces all {@link Handler} instances registered in the presented {@link Logger} to be flushed.
129 	 * 
130 	 * @param logger to flush (required)
131 	 * @return the number of {@link Handler}s flushed (may be 0 or above)
132 	 */
133 	public static final int flushAllHandlers(Logger logger) {
134 		Assert.notNull(logger, "Logger is required");
135 		
136 		int flushed = 0;
137 		
138 		Handler[] handlers = logger.getHandlers();
139 		if (handlers != null && handlers.length > 0) {
140 			for (Handler h : handlers) {
141 				flushed++;
142 				h.flush();
143 			}
144 		}
145 
146 		return flushed;
147 	}
148 }