001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU General
007: * Public License Version 2 only ("GPL") or the Common Development and Distribution
008: * License("CDDL") (collectively, the "License"). You may not use this file except in
009: * compliance with the License. You can obtain a copy of the License at
010: * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
011: * License for the specific language governing permissions and limitations under the
012: * License. When distributing the software, include this License Header Notice in
013: * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun
014: * designates this particular file as subject to the "Classpath" exception as
015: * provided by Sun in the GPL Version 2 section of the License file that
016: * accompanied this code. If applicable, add the following below the License Header,
017: * with the fields enclosed by brackets [] replaced by your own identifying
018: * information: "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Contributor(s):
021: *
022: * The Original Software is NetBeans. The Initial Developer of the Original Software
023: * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
024: * Rights Reserved.
025: *
026: * If you wish your version of this file to be governed by only the CDDL or only the
027: * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
028: * this software in this distribution under the [CDDL or GPL Version 2] license." If
029: * you do not indicate a single choice of license, a recipient has the option to
030: * distribute your version of this file under either the CDDL, the GPL Version 2 or
031: * to extend the choice of license to its licensees as provided above. However, if
032: * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
033: * the option applies only if the new code is made subject to such option by the
034: * copyright holder.
035: */
036:
037: package org.netbeans.installer.utils;
038:
039: import java.io.BufferedReader;
040: import java.io.File;
041: import java.io.FileWriter;
042: import java.io.IOException;
043: import java.io.PrintWriter;
044: import java.io.StringReader;
045: import java.util.LinkedList;
046: import java.util.List;
047: import org.netbeans.installer.utils.helper.ErrorLevel;
048:
049: /**
050: *
051: * @author Kirill Sorokin
052: */
053: public final class LogManager {
054: /////////////////////////////////////////////////////////////////////////////////
055: // Static
056: public static final int DEFAULT_LOG_LEVEL = ErrorLevel.DEBUG;
057: public static final boolean DEFAULT_LOG_TO_CONSOLE = true;
058:
059: private static File logFile;
060: private static PrintWriter logWriter;
061: private static int logLevel = DEFAULT_LOG_LEVEL;
062: private static boolean logToConsole = DEFAULT_LOG_TO_CONSOLE;
063:
064: private static int indent;
065:
066: private static boolean started = false;
067:
068: private static List<String> logCache = new LinkedList<String>();
069:
070: public static synchronized void start() {
071: // check for custom log level
072: if (System.getProperty(LOG_LEVEL_PROPERTY) != null) {
073: try {
074: logLevel = Integer.parseInt(System
075: .getProperty(LOG_LEVEL_PROPERTY));
076: } catch (NumberFormatException e) {
077: logLevel = DEFAULT_LOG_LEVEL;
078: }
079: } else {
080: logLevel = DEFAULT_LOG_LEVEL;
081: }
082:
083: // check whether we should log to console as well
084: if (System.getProperty(LOG_TO_CONSOLE_PROPERTY) != null) {
085: logToConsole = new Boolean(System
086: .getProperty(LOG_TO_CONSOLE_PROPERTY));
087: } else {
088: logToConsole = DEFAULT_LOG_TO_CONSOLE;
089: }
090:
091: // init the log file and streams
092: try {
093: if (logFile != null) {
094: logFile.getParentFile().mkdirs();
095: logFile.createNewFile();
096: logWriter = new PrintWriter(new FileWriter(logFile));
097: }
098:
099: // here is a small assumption that there will be no calls to log*(*)
100: // during the cache dumping. Otherwise we'll get a concurrent
101: // modification exception
102: for (String string : logCache) {
103: write(string);
104: }
105: } catch (IOException e) {
106: e.printStackTrace(System.err);
107: logWriter = null;
108: }
109:
110: started = true;
111: }
112:
113: public static synchronized void stop() {
114: started = false;
115:
116: logWriter.close();
117: }
118:
119: public static synchronized void indent() {
120: indent++;
121: }
122:
123: public static synchronized void unindent() {
124: indent--;
125: }
126:
127: public static synchronized void log(int level, String message) {
128: if (level <= logLevel) {
129: BufferedReader reader = new BufferedReader(
130: new StringReader(message));
131:
132: try {
133: for (String line = reader.readLine(); line != null; line = reader
134: .readLine()) {
135: String string = "["
136: + DateUtils.getFormattedTimestamp() + "]: "
137: + StringUtils.pad(INDENT, indent) + line;
138:
139: if (started) {
140: write(string);
141: } else {
142: logCache.add(string);
143: }
144: }
145: } catch (IOException e) {
146: logWriter = null;
147: ErrorManager.notifyWarning(ResourceUtils.getString(
148: LogManager.class, ERROR_CANNOT_WRITE_KEY));
149: }
150: }
151: }
152:
153: public static synchronized void log(int level, Throwable exception) {
154: log(level, StringUtils.asString(exception));
155: }
156:
157: public static synchronized void log(int level, Object object) {
158: log(level, object.toString());
159: }
160:
161: public static synchronized void log(String message) {
162: log(ErrorLevel.MESSAGE, message);
163: }
164:
165: public static synchronized void log(Throwable exception) {
166: log(ErrorLevel.MESSAGE, exception);
167: }
168:
169: public static synchronized void log(Object object) {
170: log(ErrorLevel.MESSAGE, object);
171: }
172:
173: public static synchronized void log(String message,
174: Throwable exception) {
175: log(message);
176: log(exception);
177: }
178:
179: public static synchronized void logEntry(String message) {
180: final StackTraceElement traceElement = Thread.currentThread()
181: .getStackTrace()[3];
182:
183: log(ErrorLevel.DEBUG, "entering -- "
184: + (traceElement.isNativeMethod() ? "[native] " : "")
185: + traceElement.getClassName() + "."
186: + traceElement.getMethodName() + "():"
187: + traceElement.getLineNumber());
188: log(ErrorLevel.MESSAGE, message);
189: indent();
190: }
191:
192: public static synchronized void logExit(String message) {
193: StackTraceElement traceElement = Thread.currentThread()
194: .getStackTrace()[3];
195:
196: unindent();
197: log(message);
198: log(ErrorLevel.DEBUG, "exiting -- "
199: + (traceElement.isNativeMethod() ? "[native] " : "")
200: + traceElement.getClassName() + "."
201: + traceElement.getMethodName() + "():"
202: + traceElement.getLineNumber());
203: }
204:
205: public static synchronized void logIndent(String message) {
206: log(message);
207: indent();
208: }
209:
210: public static synchronized void logUnindent(String message) {
211: unindent();
212: log(message);
213: }
214:
215: public static File getLogFile() {
216: return logFile;
217: }
218:
219: public static void setLogFile(final File logFile) {
220: LogManager.logFile = logFile;
221: }
222:
223: // private //////////////////////////////////////////////////////////////////////
224: private static void write(String string) throws IOException {
225: if (logWriter != null) {
226: logWriter.println(string);
227: logWriter.flush();
228: }
229:
230: if (logToConsole) {
231: System.out.println(string);
232: }
233: }
234:
235: /////////////////////////////////////////////////////////////////////////////////
236: // Instance
237: private LogManager() {
238: // does nothing
239: }
240:
241: /////////////////////////////////////////////////////////////////////////////////
242: // Constants
243: public static final String LOG_LEVEL_PROPERTY = "nbi.utils.log.level"; // NOI18N
244: public static final String LOG_TO_CONSOLE_PROPERTY = "nbi.utils.log.to.console"; // NOI18N
245:
246: public static final String INDENT = " "; // NOI18N
247: public static final String ERROR_CANNOT_WRITE_KEY = "LM.error.cannot.write";//NOI18N
248: }
|