All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oracle.toplink.essentials.logging.AbstractSessionLog Maven / Gradle / Ivy

There is a newer version: 2.1-60f
Show newest version
/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the "License").  You may not use this file except 
 * in compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * glassfish/bootstrap/legal/CDDLv1.0.txt or 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html. 
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * HEADER in each file and include the License file at 
 * glassfish/bootstrap/legal/CDDLv1.0.txt.  If applicable, 
 * add the following below this CDDL HEADER, with the 
 * fields enclosed by brackets "[]" replaced with your 
 * own identifying information: Portions Copyright [yyyy] 
 * [name of copyright owner]
 */
// Copyright (c) 1998, 2007, Oracle. All rights reserved.  
package oracle.toplink.essentials.logging;

import java.util.*;
import java.text.*;
import java.io.*;
import oracle.toplink.essentials.sessions.Session;
import oracle.toplink.essentials.internal.databaseaccess.Accessor;
import oracle.toplink.essentials.internal.localization.*;
import oracle.toplink.essentials.exceptions.*;
import oracle.toplink.essentials.internal.sessions.AbstractSession;

/**
 * Represents the abstract log that implements all the generic logging functions.
 * It contains a singleton SessionLog that logs messages from outside any TopLink session.
 * The singleton SessionLog can also be passed to a TopLink session when messages
 * are logged through that session.  When JDK1.4 is used, a singleton JavaLog is created.
 * Otherwise a singleton DefaultSessionLog is created.
 *
 * @see SessionLog
 * @see SessionLogEntry
 * @see DefaultSessionLog
 * @see JavaLog
 */
public abstract class AbstractSessionLog implements SessionLog, java.lang.Cloneable {

    /**
     * Represents the log level
     */
    protected int level;

    /**
     * Represents the singleton SessionLog
     */
    protected static SessionLog defaultLog;

    /**
     * Represents the session that owns this SessionLog
     */
    protected Session session;

    /**
     * Represents the session type of the session that owns this SessionLog
     */
    protected String sessionType;

    /**
     * Caches the session hash code string of the session that owns this SessionLog
     */
    protected String sessionHashCode;

    /**
     * Represents prefix to logged severe
     */
    protected static String SEVERE_PREFIX = null;

    /**
     * Represents prefix to logged warning
     */
    protected static String WARNING_PREFIX = null;

    /**
     * Represents prefix to logged info
     */
    protected static String INFO_PREFIX = null;

    /**
     * Represents prefix to logged config
     */
    protected static String CONFIG_PREFIX = null;

    /**
     * Represents prefix to logged fine
     */
    protected static String FINE_PREFIX = null;

    /**
     * Represents prefix to logged finer
     */
    protected static String FINER_PREFIX = null;

    /**
     * Represents prefix to logged finest
     */
    protected static String FINEST_PREFIX = null;

    /**
     * Cached TopLink prefix string.
     */
    protected static String TOPLINK_PREFIX = null;

    /**
     * Connection string
     */
    protected static String CONNECTION_STRING = "Connection";

    /**
     * Thread string
     */
    protected static String THREAD_STRING = "Thread";

    /**
     * Represents the writer that will receive the formatted log entries
     */
    protected Writer writer;
    
    /**
     * Format use to print the current date/time.
     */
    protected DateFormat dateFormat;
    
    /**
     * Allows the printing of the stack to be explictitly disabled/enabled.
     * CR #3870467.
     * null value is default behavoir of determining from log level.
     */
    protected Boolean shouldLogExceptionStackTrace;
    
    /**
     * Allows the printing of the date to be explictitly disabled/enabled.
     * CR #3870467.
     * null value is default behavoir of determining from log level.
     */
    protected Boolean shouldPrintDate;
    
    /**
     * Allows the printing of the thread to be explictitly disabled/enabled.
     * CR #3870467.
     * null value is default behavoir of determining from log level.
     */
    protected Boolean shouldPrintThread;
        
    /**
     * Allows the printing of the session to be explictitly disabled/enabled.
     * CR #3870467.
     * null value is default behavoir of determining from log level.
     */
    protected Boolean shouldPrintSession;

    /**
     * Allows the printing of the connection to be explictitly disabled/enabled.
     * CR #4157545.
     * null value is default behavoir of determining from log level.
     */
    protected Boolean shouldPrintConnection;

    /**
     * PUBLIC:
     * Create a new AbstractSessionLog
     */
    public AbstractSessionLog() {
        this.writer = new PrintWriter(System.out);
    }

    /**
     * PUBLIC:
     * 

* Return the log level. It is used when session is not available. *

* * @return the log level *

*/ public int getLevel() { return getLevel(null); } /** * PUBLIC: *

* Return the log level. Category is only needed in JavaLog * to extract name space for the Logger which the log level belongs to. *

* * @return the log level *

* @param category the string representation of a TopLink category, e.g. "sql", "transaction" ... *

*/ public int getLevel(String category) { return level; } /** * PUBLIC: *

* Set the log level. It is used when session is not available. *

* * @param level the new log level *

*/ public void setLevel(int level) { setLevel(level, null); } /** * PUBLIC: *

* Set the log level. Category is only needed in JavaLog * to extract name space for the Logger which the log level belongs to. *

* * @param level the new log level * @param category the string representation of a TopLink category, e.g. "sql", "transaction" ... *

*/ public void setLevel(int level, String category) { this.level = level; } /** * PUBLIC: *

* Check if a message of the given level would actually be logged. * It is used when session is not available. *

* * @return true if the given message level will be logged *

* @param level the log request level *

*/ public boolean shouldLog(int level) { return shouldLog(level, null); } /** * PUBLIC: *

* Check if a message of the given level would actually be logged. Category * is only needed in JavaLog to extract name space for the Logger which the log * level belongs to. !isOff() is checked to screen out the possibility when both * log level and log request level are set to OFF. *

* * @return true if the given message level will be logged *

* @param level the log request level * @param category the string representation of a TopLink category, e.g. "sql", "transaction" ...*

*

*/ public boolean shouldLog(int level, String category) { return (this.level <= level) && !isOff(); } /** * PUBLIC: *

* Return the singleton SessionLog. If the singleton SessionLog does not exist, * a new one is created based on the version of JDK being used from the Version class. *

* * @return the singleton SessionLog *

*/ public static SessionLog getLog() { if (defaultLog == null) { defaultLog = new DefaultSessionLog(); } return defaultLog; } /** * PUBLIC: *

* Set the singleton SessionLog. *

* * @param sessionLog a SessionLog *

*/ public static void setLog(SessionLog sessionLog) { defaultLog = sessionLog; defaultLog.setSession(null); } /** * PUBLIC: *

* Get the session. *

* * @return session *

*/ public Session getSession() { return this.session; } /** * PUBLIC: *

* Set the session. *

* * @param session a Session *

*/ public void setSession(Session session) { if (this.session == null) { this.session = session; buildSessionType(); buildSessionHashCode(); } } /** * PUBLIC: *

* Log a message that does not need to be translated. This method is intended for * external use when logging messages are wanted within the TopLink output. *

* * @param level the log request level value *

* @param message the string message *

*/ public void log(int level, String message) { if (!shouldLog(level)) { return; } //Bug#4566524 Pass in false for external use log(level, message, (Object[])null, false); } /** * INTERNAL: *

* Log a message with one parameter that needs to be translated. *

* * @param level the log request level value *

* @param message the string message *

* @param param a parameter of the message *

*/ public void log(int level, String message, Object param) { if (!shouldLog(level)) { return; } log(level, message, new Object[] { param }); } /** * INTERNAL: *

* Log a message with two parameters that needs to be translated. *

* * @param level the log request level value *

* @param message the string message *

* @param param1 a parameter of the message *

* @param param2 second parameter of the message *

*/ public void log(int level, String message, Object param1, Object param2) { if (!shouldLog(level)) { return; } log(level, message, new Object[] { param1, param2 }); } /** * INTERNAL: *

* Log a message with three parameters that needs to be translated. *

* * @param level the log request level value *

* @param message the string message *

* @param param1 a parameter of the message *

* @param param2 second parameter of the message *

* @param param3 third parameter of the message *

*/ public void log(int level, String message, Object param1, Object param2, Object param3) { if (!shouldLog(level)) { return; } log(level, message, new Object[] { param1, param2, param3 }); } /** * INTERNAL: *

* Log a message with an array of parameters that needs to be translated. *

* * @param level the log request level value *

* @param message the string message *

* @param params array of parameters to the message *

*/ public void log(int level, String message, Object[] params) { log(level, message, params, true); } /** * INTERNAL: *

* Log a message. shouldTranslate determines if the message needs to be translated. *

* * @param level the log request level *

* @param message the string message *

* @param params array of parameters to the message *

* @param shouldTranslate true if the message needs to be translated *

*/ public void log(int level, String message, Object[] params, boolean shouldTranslate) { if (!shouldLog(level)) { return; } log(new SessionLogEntry(level, null, message, params, null, shouldTranslate)); } /** * PUBLIC: *

* Log a SessionLogEntry *

* * @param entry SessionLogEntry that holds all the information for a TopLink logging event *

*/ public abstract void log(SessionLogEntry sessionLogEntry); /** * By default the session (and its connection is available) are printed, * this can be turned off. */ public boolean shouldPrintSession() { return (shouldPrintSession == null) || shouldPrintSession.booleanValue(); } /** * By default the session (and its connection is available) are printed, * this can be turned off. */ public void setShouldPrintSession(boolean shouldPrintSession) { if (shouldPrintSession) { this.shouldPrintSession = Boolean.TRUE; } else { this.shouldPrintSession = Boolean.FALSE; } } /** * By default the connection is printed, this can be turned off. */ public boolean shouldPrintConnection() { return (shouldPrintConnection == null) || shouldPrintConnection.booleanValue(); } /** * By default the connection is printed, this can be turned off. */ public void setShouldPrintConnection(boolean shouldPrintConnection) { if (shouldPrintConnection) { this.shouldPrintConnection = Boolean.TRUE; } else { this.shouldPrintConnection = Boolean.FALSE; } } /** * By default the stack is logged for FINER or less (finest). * The logging of the stack can also be explicitly turned on or off. */ public boolean shouldLogExceptionStackTrace() { if (shouldLogExceptionStackTrace == null) { return getLevel() <= FINER; } else { return shouldLogExceptionStackTrace.booleanValue(); } } /** * By default the stack is logged for FINER or less (finest). * The logging of the stack can also be explicitly turned on or off. */ public void setShouldLogExceptionStackTrace(boolean shouldLogExceptionStackTrace) { if (shouldLogExceptionStackTrace) { this.shouldLogExceptionStackTrace = Boolean.TRUE; } else { this.shouldLogExceptionStackTrace = Boolean.FALSE; } } /** * By default the date is always printed, but can be turned off. */ public boolean shouldPrintDate() { return (shouldPrintDate == null) || (shouldPrintDate.booleanValue()); } /** * By default the date is always printed, but can be turned off. */ public void setShouldPrintDate(boolean shouldPrintDate) { if (shouldPrintDate) { this.shouldPrintDate = Boolean.TRUE; } else { this.shouldPrintDate = Boolean.FALSE; } } /** * By default the thread is logged for FINE or less (finer,etc.). * The logging of the thread can also be explicitly turned on or off. */ public boolean shouldPrintThread() { if (shouldPrintThread == null) { return getLevel() <= FINE; } else { return shouldPrintThread.booleanValue(); } } /** * By default the thread is logged for FINE or less (finer,etc.). * The logging of the thread can also be explicitly turned on or off. */ public void setShouldPrintThread(boolean shouldPrintThread) { if (shouldPrintThread) { this.shouldPrintThread = Boolean.TRUE; } else { this.shouldPrintThread = Boolean.FALSE; } } /** * PUBLIC: *

* Return the writer that will receive the formatted log entries. *

* * @return the log writer *

*/ public Writer getWriter() { return writer; } /** * PUBLIC: *

* Set the writer that will receive the formatted log entries. *

* * @param writer the log writer *

*/ public void setWriter(Writer writer) { this.writer = writer; } /** * Build and return a date format. * The default is a format that is sortable and easily parsed. * @return the date format */ protected DateFormat buildDefaultDateFormat() { return new SimpleDateFormat("yyyy.MM.dd hh:mm:ss.SSS"); } /** * PUBLIC: * Return the date format to be used when printing a log entry date. * @return the date format */ public DateFormat getDateFormat() { if (dateFormat == null) { dateFormat = this.buildDefaultDateFormat(); } return dateFormat; } /** * Return the specified date and/or time information in string. * The format will be determined by the date format settings. */ protected String getDateString(Date date) { return this.getDateFormat().format(date); } /** * Return the supplement detail information including date, session, thread and connection. */ protected String getSupplementDetailString(SessionLogEntry entry) { StringWriter writer = new StringWriter(); if (shouldPrintDate()) { writer.write(getDateString(entry.getDate())); writer.write("--"); } if (shouldPrintSession() && (entry.getSession() != null)) { writer.write(this.getSessionString(entry.getSession())); writer.write("--"); } if (shouldPrintConnection() && (entry.getConnection() != null)) { writer.write(this.getConnectionString(entry.getConnection())); writer.write("--"); } if (shouldPrintThread()) { writer.write(this.getThreadString(entry.getThread())); writer.write("--"); } return writer.toString(); } /** * Return the current session including the type and id. */ protected String getSessionString(Session session) { // For bug 3422759 the session to log against should be the one in the // event, not the static one in the SessionLog, for there are many // sessions but only one SessionLog. if (session != null) { return ((AbstractSession)session).getLogSessionString(); } else { return getSessionString(); } } /** * Return the current session type. */ protected void buildSessionType() { if (session != null) { sessionType = ((AbstractSession)session).getSessionTypeString(); } else { sessionType = null; } } /** * Return the current session hash code. */ protected void buildSessionHashCode() { if (session != null) { sessionHashCode = String.valueOf(System.identityHashCode(session)); } else { sessionHashCode = null; } } /** * Return the current session including the type and id. */ protected String getSessionString() { return sessionType + "(" + sessionHashCode + ")"; } /** * Return the specified connection information. */ protected String getConnectionString(Accessor connection) { // Bug 3630182 - if possible, print the actual connection's hashcode instead of just the accessor if (connection.getDatasourceConnection() == null){ return CONNECTION_STRING + "(" + String.valueOf(System.identityHashCode(connection)) + ")"; } else { return CONNECTION_STRING + "(" + String.valueOf(System.identityHashCode(connection.getDatasourceConnection())) + ")"; } } /** * Return the specified thread information. */ protected String getThreadString(Thread thread) { return THREAD_STRING + "(" + String.valueOf(thread) + ")"; } /** * Print the prefix string representing TopLink logging */ //Bug3135111 Prefix strings are not translated until the first time they are used. protected void printPrefixString(int level) { try { switch (level) { case SEVERE: if (SEVERE_PREFIX == null) { SEVERE_PREFIX = LoggingLocalization.buildMessage("toplink_severe"); } this.getWriter().write(SEVERE_PREFIX); break; case WARNING: if (WARNING_PREFIX == null) { WARNING_PREFIX = LoggingLocalization.buildMessage("toplink_warning"); } this.getWriter().write(WARNING_PREFIX); break; case INFO: if (INFO_PREFIX == null) { INFO_PREFIX = LoggingLocalization.buildMessage("toplink_info"); } this.getWriter().write(INFO_PREFIX); break; case CONFIG: if (CONFIG_PREFIX == null) { CONFIG_PREFIX = LoggingLocalization.buildMessage("toplink_config"); } this.getWriter().write(CONFIG_PREFIX); break; case FINE: if (FINE_PREFIX == null) { FINE_PREFIX = LoggingLocalization.buildMessage("toplink_fine"); } this.getWriter().write(FINE_PREFIX); break; case FINER: if (FINER_PREFIX == null) { FINER_PREFIX = LoggingLocalization.buildMessage("toplink_finer"); } this.getWriter().write(FINER_PREFIX); break; case FINEST: if (FINEST_PREFIX == null) { FINEST_PREFIX = LoggingLocalization.buildMessage("toplink_finest"); } this.getWriter().write(FINEST_PREFIX); break; default: if (TOPLINK_PREFIX == null) { TOPLINK_PREFIX = LoggingLocalization.buildMessage("toplink"); } this.getWriter().write(TOPLINK_PREFIX); } } catch (IOException exception) { throw ValidationException.logIOError(exception); } } /** * PUBLIC: * Set the date format to be used when * printing a log entry date. * @param dateFormat java.text.DateFormat */ public void setDateFormat(DateFormat dateFormat) { this.dateFormat = dateFormat; } /** * Return the formatted message based on the information from the given SessionLogEntry. * The message will either be translated and formatted or formatted only depending * on if the shouldTranslate flag is set to true of false. */ protected String formatMessage(SessionLogEntry entry) { String message = entry.getMessage(); if (entry.shouldTranslate()) { if (entry.getLevel() > FINE) { message = LoggingLocalization.buildMessage(message, entry.getParameters()); } else { message = TraceLocalization.buildMessage(message, entry.getParameters()); } } else { if (message.indexOf("{0") >= 0) { message = java.text.MessageFormat.format(message, entry.getParameters()); } } return message; } /** * PUBLIC: *

* Log a throwable at FINER level. *

* * @param throwable a Throwable *

*/ public void throwing(Throwable throwable) { if (shouldLog(FINER)) { SessionLogEntry entry = new SessionLogEntry(null, throwable); entry.setLevel(FINER); log(entry); } } /** * INTERNAL: * Translate the string value of the log level to the constant value. * If value is null or invalid use the default. */ public static int translateStringToLoggingLevel(String loggingLevel){ if (loggingLevel == null){ return INFO; } else if (loggingLevel.equals("OFF")){ return OFF; } else if (loggingLevel.equals("SEVERE")){ return SEVERE; } else if (loggingLevel.equals("WARNING")){ return WARNING; } else if (loggingLevel.equals("INFO")){ return INFO; } else if (loggingLevel.equals("CONFIG")){ return CONFIG; } else if (loggingLevel.equals("FINE")){ return FINE; } else if (loggingLevel.equals("FINER")){ return FINER; } else if (loggingLevel.equals("FINEST")){ return FINEST; } else if (loggingLevel.equals("ALL")){ return ALL; } return INFO; } /** * INTERNAL: * Translate the string value of the log level to the constant value. * If value is null or invalid use the default. */ public static String translateLoggingLevelToString(int loggingLevel){ if (loggingLevel == OFF){ return "OFF"; } else if (loggingLevel == SEVERE){ return "SEVERE"; } else if (loggingLevel == WARNING){ return "WARNING"; } else if (loggingLevel == INFO){ return "INFO"; } else if (loggingLevel == CONFIG){ return "CONFIG"; } else if (loggingLevel == FINE){ return "FINE"; } else if (loggingLevel == FINER){ return "FINER"; } else if (loggingLevel == FINEST){ return "FINEST"; } else if (loggingLevel == ALL){ return "ALL"; } return "INFO"; } /** * PUBLIC: *

* This method is called when a severe level message needs to be logged. * The message will be translated *

* * @param message the message key *

*/ public void severe(String message) { log(SEVERE, message, (Object[])null); } /** * PUBLIC: *

* This method is called when a warning level message needs to be logged. * The message will be translated *

* * @param message the message key *

*/ public void warning(String message) { log(WARNING, message, (Object[])null); } /** * PUBLIC: *

* This method is called when a info level message needs to be logged. * The message will be translated *

* * @param message the message key *

*/ public void info(String message) { log(INFO, message, (Object[])null); } /** * PUBLIC: *

* This method is called when a config level message needs to be logged. * The message will be translated *

* * @param message the message key *

*/ public void config(String message) { log(CONFIG, message, (Object[])null); } /** * PUBLIC: *

* This method is called when a fine level message needs to be logged. * The message will be translated *

* * @param message the message key *

*/ public void fine(String message) { log(FINE, message, (Object[])null); } /** * PUBLIC: *

* This method is called when a finer level message needs to be logged. * The message will be translated *

* * @param message the message key *

*/ public void finer(String message) { log(FINER, message, (Object[])null); } /** * PUBLIC: *

* This method is called when a finest level message needs to be logged. * The message will be translated *

* * @param message the message key *

*/ public void finest(String message) { log(FINEST, message, (Object[])null); } /** * PUBLIC: *

* Log a throwable with level. *

* * @param level the log request level value *

* @param throwable a Throwable *

*/ public void logThrowable(int level, Throwable throwable) { // Must not create the log if not logging as is a performance issue. if (shouldLog(level)) { log(new SessionLogEntry(null, level, null, throwable)); } } /** * PUBLIC: * Check if the log level is set to off. */ public boolean isOff() { return this.level == OFF; } /** * INTERNAL: * Each session owns its own session log because session is stored in the session log */ public Object clone() { try { return super.clone(); } catch (Exception exception) { return null; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy