Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2008-2019 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright (C) 2008-2019 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.util;
import java.io.Serializable;
import java.util.EnumSet;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.unboundid.asn1.ASN1Buffer;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.ldap.protocol.LDAPResponse;
import com.unboundid.ldap.sdk.AbstractConnectionPool;
import com.unboundid.ldap.sdk.DisconnectType;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.InternalSDKHelper;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPRequest;
import com.unboundid.ldap.sdk.Version;
import com.unboundid.ldif.LDIFRecord;
/**
* This class provides a means of enabling and configuring debugging in the LDAP
* SDK.
*
* Access to debug information can be enabled through applications that use the
* SDK by calling the {@link Debug#setEnabled} methods, or it can also be
* enabled without any code changes through the use of system properties. In
* particular, the {@link Debug#PROPERTY_DEBUG_ENABLED},
* {@link Debug#PROPERTY_DEBUG_LEVEL}, and {@link Debug#PROPERTY_DEBUG_TYPE}
* properties may be used to control debugging without the need to alter any
* code within the application that uses the SDK.
*
* The LDAP SDK debugging subsystem uses the Java logging framework available
* through the {@code java.util.logging} package with a logger name of
* "{@code com.unboundid.ldap.sdk}". The {@link Debug#getLogger} method may
* be used to access the logger instance used by the LDAP SDK.
*
*
Example
* The following example demonstrates the process that may be used to enable
* debugging within the LDAP SDK and write information about all messages with
* a {@code WARNING} level or higher to a specified file:
*
*/
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class Debug
implements Serializable
{
/**
* The name of the system property that will be used to enable debugging in
* the UnboundID LDAP SDK for Java. The fully-qualified name for this
* property is "{@code com.unboundid.ldap.sdk.debug.enabled}". If it is set,
* then it should have a value of either "true" or "false".
*/
public static final String PROPERTY_DEBUG_ENABLED =
"com.unboundid.ldap.sdk.debug.enabled";
/**
* The name of the system property that may be used to indicate whether stack
* trace information for the thread calling the debug method should be
* included in debug log messages. The fully-qualified name for this property
* is "{@code com.unboundid.ldap.sdk.debug.includeStackTrace}". If it is set,
* then it should have a value of either "true" or "false".
*/
public static final String PROPERTY_INCLUDE_STACK_TRACE =
"com.unboundid.ldap.sdk.debug.includeStackTrace";
/**
* The name of the system property that will be used to set the initial level
* for the debug logger. The fully-qualified name for this property is
* "{@code com.unboundid.ldap.sdk.debug.level}". If it is set, then it should
* be one of the strings "{@code SEVERE}", "{@code WARNING}", "{@code INFO}",
* "{@code CONFIG}", "{@code FINE}", "{@code FINER}", or "{@code FINEST}".
*/
public static final String PROPERTY_DEBUG_LEVEL =
"com.unboundid.ldap.sdk.debug.level";
/**
* The name of the system property that will be used to indicate that
* debugging should be enabled for specific types of messages. The
* fully-qualified name for this property is
* "{@code com.unboundid.ldap.sdk.debug.type}". If it is set, then it should
* be a comma-delimited list of the names of the desired debug types. See the
* {@link DebugType} enum for the available debug types.
*/
public static final String PROPERTY_DEBUG_TYPE =
"com.unboundid.ldap.sdk.debug.type";
/**
* The name of the system property that will be used to indicate whether the
* LDAP SDK should default to including information about the exception's
* cause in an exception message obtained from the
* {@link StaticUtils#getExceptionMessage(Throwable)} method. By default,
* the cause will not be included in most messages.
*/
public static final String PROPERTY_INCLUDE_CAUSE_IN_EXCEPTION_MESSAGES =
"com.unboundid.ldap.sdk.debug.includeCauseInExceptionMessages";
/**
* The name of the system property that will be used to indicate whether the
* LDAP SDK should default to including a full stack trace (albeit in
* condensed form) in an exception message obtained from the
* {@link StaticUtils#getExceptionMessage(Throwable)} method. By default,
* stack traces will not be included in most messages.
*/
public static final String
PROPERTY_INCLUDE_STACK_TRACE_IN_EXCEPTION_MESSAGES =
"com.unboundid.ldap.sdk.debug.includeStackTraceInExceptionMessages";
/**
* The name that will be used for the Java logger that will actually handle
* the debug messages if debugging is enabled.
*/
public static final String LOGGER_NAME = "com.unboundid.ldap.sdk";
/**
* The logger that will be used to handle the debug messages if debugging is
* enabled.
*/
private static final Logger logger = Logger.getLogger(LOGGER_NAME);
/**
* The serial version UID for this serializable class.
*/
private static final long serialVersionUID = -6079754380415146030L;
// Indicates whether any debugging is currently enabled for the SDK.
private static boolean debugEnabled;
// Indicates whether to capture a thread stack trace whenever a debug message
// is logged.
private static boolean includeStackTrace;
// The set of debug types for which debugging is enabled.
private static EnumSet debugTypes;
static
{
initialize(StaticUtils.getSystemProperties(PROPERTY_DEBUG_ENABLED,
PROPERTY_DEBUG_LEVEL, PROPERTY_DEBUG_TYPE,
PROPERTY_INCLUDE_STACK_TRACE));
}
/**
* Prevent this class from being instantiated.
*/
private Debug()
{
// No implementation is required.
}
/**
* Initializes this debugger with the default settings. Debugging will be
* disabled, the set of debug types will include all types, and the debug
* level will be "ALL".
*/
public static void initialize()
{
includeStackTrace = false;
debugEnabled = false;
debugTypes = EnumSet.allOf(DebugType.class);
StaticUtils.setLoggerLevel(logger, Level.ALL);
}
/**
* Initializes this debugger with settings from the provided set of
* properties. Any debug setting that isn't configured in the provided
* properties will be initialized with its default value.
*
* @param properties The set of properties to use to initialize this
* debugger.
*/
public static void initialize(final Properties properties)
{
// First, apply the default values for the properties.
initialize();
if ((properties == null) || properties.isEmpty())
{
// No properties were provided, so we don't need to do anything.
return;
}
final String enabledProp = properties.getProperty(PROPERTY_DEBUG_ENABLED);
if ((enabledProp != null) && (! enabledProp.isEmpty()))
{
if (enabledProp.equalsIgnoreCase("true"))
{
debugEnabled = true;
}
else if (enabledProp.equalsIgnoreCase("false"))
{
debugEnabled = false;
}
else
{
throw new IllegalArgumentException("Invalid value '" + enabledProp +
"' for property " +
PROPERTY_DEBUG_ENABLED +
". The value must be either " +
"'true' or 'false'.");
}
}
final String stackProp =
properties.getProperty(PROPERTY_INCLUDE_STACK_TRACE);
if ((stackProp != null) && (! stackProp.isEmpty()))
{
if (stackProp.equalsIgnoreCase("true"))
{
includeStackTrace = true;
}
else if (stackProp.equalsIgnoreCase("false"))
{
includeStackTrace = false;
}
else
{
throw new IllegalArgumentException("Invalid value '" + stackProp +
"' for property " +
PROPERTY_INCLUDE_STACK_TRACE +
". The value must be either " +
"'true' or 'false'.");
}
}
final String typesProp = properties.getProperty(PROPERTY_DEBUG_TYPE);
if ((typesProp != null) && (! typesProp.isEmpty()))
{
debugTypes = EnumSet.noneOf(DebugType.class);
final StringTokenizer t = new StringTokenizer(typesProp, ", ");
while (t.hasMoreTokens())
{
final String debugTypeName = t.nextToken();
final DebugType debugType = DebugType.forName(debugTypeName);
if (debugType == null)
{
// Throw a runtime exception to indicate that the debug type is
// invalid.
throw new IllegalArgumentException("Invalid value '" + debugTypeName +
"' for property " + PROPERTY_DEBUG_TYPE +
". Allowed values include: " +
DebugType.getTypeNameList() + '.');
}
else
{
debugTypes.add(debugType);
}
}
}
final String levelProp = properties.getProperty(PROPERTY_DEBUG_LEVEL);
if ((levelProp != null) && (! levelProp.isEmpty()))
{
StaticUtils.setLoggerLevel(logger, Level.parse(levelProp));
}
}
/**
* Retrieves the logger that will be used to write the debug messages.
*
* @return The logger that will be used to write the debug messages.
*/
public static Logger getLogger()
{
return logger;
}
/**
* Indicates whether any form of debugging is enabled.
*
* @return {@code true} if debugging is enabled, or {@code false} if not.
*/
public static boolean debugEnabled()
{
return debugEnabled;
}
/**
* Indicates whether debugging is enabled for messages of the specified debug
* type.
*
* @param debugType The debug type for which to make the determination.
*
* @return {@code true} if debugging is enabled for messages of the specified
* debug type, or {@code false} if not.
*/
public static boolean debugEnabled(final DebugType debugType)
{
return (debugEnabled && debugTypes.contains(debugType));
}
/**
* Specifies whether debugging should be enabled. If it should be, then it
* will be enabled for all debug types.
*
* @param enabled Specifies whether debugging should be enabled.
*/
public static void setEnabled(final boolean enabled)
{
debugTypes = EnumSet.allOf(DebugType.class);
debugEnabled = enabled;
}
/**
* Specifies whether debugging should be enabled. If it should be, then it
* will be enabled for all debug types in the provided set.
*
* @param enabled Specifies whether debugging should be enabled.
* @param types The set of debug types that should be enabled. It may be
* {@code null} or empty to indicate that it should be for
* all debug types.
*/
public static void setEnabled(final boolean enabled,
final Set types)
{
if ((types == null) || types.isEmpty())
{
debugTypes = EnumSet.allOf(DebugType.class);
}
else
{
debugTypes = EnumSet.copyOf(types);
}
debugEnabled = enabled;
}
/**
* Indicates whether log messages should include a stack trace of the thread
* that invoked the debug method.
*
* @return {@code true} if log messages should include a stack trace of the
* thread that invoked the debug method, or {@code false} if not.
*/
public static boolean includeStackTrace()
{
return includeStackTrace;
}
/**
* Specifies whether log messages should include a stack trace of the thread
* that invoked the debug method.
*
* @param includeStackTrace Indicates whether log messages should include a
* stack trace of the thread that invoked the debug
* method.
*/
public static void setIncludeStackTrace(final boolean includeStackTrace)
{
Debug.includeStackTrace = includeStackTrace;
}
/**
* Retrieves the set of debug types that will be used if debugging is enabled.
*
* @return The set of debug types that will be used if debugging is enabled.
*/
public static EnumSet getDebugTypes()
{
return debugTypes;
}
/**
* Writes debug information about the provided exception, if appropriate. If
* it is to be logged, then it will be sent to the underlying logger using the
* {@code WARNING} level.
*
* @param t The exception for which debug information should be written.
*/
public static void debugException(final Throwable t)
{
if (debugEnabled && debugTypes.contains(DebugType.EXCEPTION))
{
debugException(Level.WARNING, t);
}
}
/**
* Writes debug information about the provided exception, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param t The exception for which debug information should be written.
*/
public static void debugException(final Level l, final Throwable t)
{
if (debugEnabled && debugTypes.contains(DebugType.EXCEPTION))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("caughtException=\"");
StaticUtils.getStackTrace(t, buffer);
buffer.append('"');
logger.log(l, buffer.toString(), t);
}
}
/**
* Writes debug information to indicate that a connection has been
* established, if appropriate. If it is to be logged, then it will be sent
* to the underlying logger using the {@code INFO} level.
*
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
*/
public static void debugConnect(final String h, final int p)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
debugConnect(Level.INFO, h, p, null);
}
}
/**
* Writes debug information to indicate that a connection has been
* established, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
*/
public static void debugConnect(final Level l, final String h, final int p)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
debugConnect(l, h, p, null);
}
}
/**
* Writes debug information to indicate that a connection has been
* established, if appropriate. If it is to be logged, then it will be sent
* to the underlying logger using the {@code INFO} level.
*
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
* @param c The connection object for the connection that has been
* established. It may be {@code null} for historic reasons, but
* should be non-{@code null} in new uses.
*/
public static void debugConnect(final String h, final int p,
final LDAPConnection c)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
debugConnect(Level.INFO, h, p, c);
}
}
/**
* Writes debug information to indicate that a connection has been
* established, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
* @param c The connection object for the connection that has been
* established. It may be {@code null} for historic reasons, but
* should be non-{@code null} in new uses.
*/
public static void debugConnect(final Level l, final String h, final int p,
final LDAPConnection c)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("connectedTo=\"");
buffer.append(h);
buffer.append(':');
buffer.append(p);
buffer.append('"');
if (c != null)
{
buffer.append(" connectionID=");
buffer.append(c.getConnectionID());
final String connectionName = c.getConnectionName();
if (connectionName != null)
{
buffer.append(" connectionName=\"");
buffer.append(connectionName);
buffer.append('"');
}
final String connectionPoolName = c.getConnectionPoolName();
if (connectionPoolName != null)
{
buffer.append(" connectionPoolName=\"");
buffer.append(connectionPoolName);
buffer.append('"');
}
}
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information to indicate that a connection has been
* terminated, if appropriate. If it is to be logged, then it will be sent
* to the underlying logger using the {@code INFO} level.
*
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
* @param t The disconnect type.
* @param m The disconnect message, if available.
* @param e The disconnect cause, if available.
*/
public static void debugDisconnect(final String h, final int p,
final DisconnectType t, final String m,
final Throwable e)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
debugDisconnect(Level.INFO, h, p, null, t, m, e);
}
}
/**
* Writes debug information to indicate that a connection has been
* terminated, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
* @param t The disconnect type.
* @param m The disconnect message, if available.
* @param e The disconnect cause, if available.
*/
public static void debugDisconnect(final Level l, final String h, final int p,
final DisconnectType t, final String m,
final Throwable e)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
debugDisconnect(l, h, p, null, t, m, e);
}
}
/**
* Writes debug information to indicate that a connection has been
* terminated, if appropriate. If it is to be logged, then it will be sent
* to the underlying logger using the {@code INFO} level.
*
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
* @param c The connection object for the connection that has been closed.
* It may be {@code null} for historic reasons, but should be
* non-{@code null} in new uses.
* @param t The disconnect type.
* @param m The disconnect message, if available.
* @param e The disconnect cause, if available.
*/
public static void debugDisconnect(final String h, final int p,
final LDAPConnection c,
final DisconnectType t, final String m,
final Throwable e)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
debugDisconnect(Level.INFO, h, p, c, t, m, e);
}
}
/**
* Writes debug information to indicate that a connection has been
* terminated, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param h The address of the server to which the connection was
* established.
* @param p The port of the server to which the connection was established.
* @param c The connection object for the connection that has been closed.
* It may be {@code null} for historic reasons, but should be
* non-{@code null} in new uses.
* @param t The disconnect type.
* @param m The disconnect message, if available.
* @param e The disconnect cause, if available.
*/
public static void debugDisconnect(final Level l, final String h, final int p,
final LDAPConnection c,
final DisconnectType t, final String m,
final Throwable e)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECT))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
if (c != null)
{
buffer.append("connectionID=");
buffer.append(c.getConnectionID());
final String connectionName = c.getConnectionName();
if (connectionName != null)
{
buffer.append(" connectionName=\"");
buffer.append(connectionName);
buffer.append('"');
}
final String connectionPoolName = c.getConnectionPoolName();
if (connectionPoolName != null)
{
buffer.append(" connectionPoolName=\"");
buffer.append(connectionPoolName);
buffer.append('"');
}
buffer.append(' ');
}
buffer.append("disconnectedFrom=\"");
buffer.append(h);
buffer.append(':');
buffer.append(p);
buffer.append("\" disconnectType=\"");
buffer.append(t.name());
buffer.append('"');
if (m != null)
{
buffer.append("\" disconnectMessage=\"");
buffer.append(m);
buffer.append('"');
}
if (e != null)
{
buffer.append("\" disconnectCause=\"");
StaticUtils.getStackTrace(e, buffer);
buffer.append('"');
}
logger.log(l, buffer.toString(), c);
}
}
/**
* Writes debug information about the provided request, if appropriate. If
* it is to be logged, then it will be sent to the underlying logger using the
* {@code INFO} level.
*
* @param r The LDAP request for which debug information should be written.
*/
public static void debugLDAPRequest(final LDAPRequest r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
debugLDAPRequest(Level.INFO, r, -1, null);
}
}
/**
* Writes debug information about the provided request, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param r The LDAP request for which debug information should be written.
*/
public static void debugLDAPRequest(final Level l, final LDAPRequest r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
debugLDAPRequest(l, r, -1, null);
}
}
/**
* Writes debug information about the provided request, if appropriate. If
* it is to be logged, then it will be sent to the underlying logger using the
* {@code INFO} level.
*
* @param r The LDAP request for which debug information should be written.
* @param i The message ID for the request that will be sent. It may be
* negative if no message ID is available.
* @param c The connection on which the request will be sent. It may be
* {@code null} for historic reasons, but should be
* non-{@code null} in new uses.
*/
public static void debugLDAPRequest(final LDAPRequest r, final int i,
final LDAPConnection c)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
debugLDAPRequest(Level.INFO, r, i, c);
}
}
/**
* Writes debug information about the provided request, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param r The LDAP request for which debug information should be written.
* @param i The message ID for the request that will be sent. It may be
* negative if no message ID is available.
* @param c The connection on which the request will be sent. It may be
* {@code null} for historic reasons, but should be
* non-{@code null} in new uses.
*/
public static void debugLDAPRequest(final Level l, final LDAPRequest r,
final int i, final LDAPConnection c)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
debugLDAPRequest(Level.INFO, String.valueOf(r), i, c);
}
}
/**
* Writes debug information about the provided request, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param s A string representation of the LDAP request for which debug
* information should be written.
* @param i The message ID for the request that will be sent. It may be
* negative if no message ID is available.
* @param c The connection on which the request will be sent. It may be
* {@code null} for historic reasons, but should be
* non-{@code null} in new uses.
*/
public static void debugLDAPRequest(final Level l, final String s,
final int i, final LDAPConnection c)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
if (c != null)
{
buffer.append("connectionID=");
buffer.append(c.getConnectionID());
final String connectionName = c.getConnectionName();
if (connectionName != null)
{
buffer.append(" connectionName=\"");
buffer.append(connectionName);
buffer.append('"');
}
final String connectionPoolName = c.getConnectionPoolName();
if (connectionPoolName != null)
{
buffer.append(" connectionPoolName=\"");
buffer.append(connectionPoolName);
buffer.append('"');
}
buffer.append(" connectedTo=\"");
buffer.append(c.getConnectedAddress());
buffer.append(':');
buffer.append(c.getConnectedPort());
buffer.append("\" ");
try
{
final int soTimeout = InternalSDKHelper.getSoTimeout(c);
buffer.append("socketTimeoutMillis=");
buffer.append(soTimeout);
buffer.append(' ');
} catch (final Exception e) {}
}
if (i >= 0)
{
buffer.append("messageID=");
buffer.append(i);
buffer.append(' ');
}
buffer.append("sendingLDAPRequest=\"");
buffer.append(s);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about the provided result, if appropriate. If
* it is to be logged, then it will be sent to the underlying logger using the
* {@code INFO} level.
*
* @param r The result for which debug information should be written.
*/
public static void debugLDAPResult(final LDAPResponse r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
debugLDAPResult(Level.INFO, r, null);
}
}
/**
* Writes debug information about the provided result, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param r The result for which debug information should be written.
*/
public static void debugLDAPResult(final Level l, final LDAPResponse r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
debugLDAPResult(l, r, null);
}
}
/**
* Writes debug information about the provided result, if appropriate. If
* it is to be logged, then it will be sent to the underlying logger using the
* {@code INFO} level.
*
* @param r The result for which debug information should be written.
* @param c The connection on which the response was received. It may be
* {@code null} for historic reasons, but should be
* non-{@code null} in new uses.
*/
public static void debugLDAPResult(final LDAPResponse r,
final LDAPConnection c)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
debugLDAPResult(Level.INFO, r, c);
}
}
/**
* Writes debug information about the provided result, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param r The result for which debug information should be written.
* @param c The connection on which the response was received. It may be
* {@code null} for historic reasons, but should be
* non-{@code null} in new uses.
*/
public static void debugLDAPResult(final Level l, final LDAPResponse r,
final LDAPConnection c)
{
if (debugEnabled && debugTypes.contains(DebugType.LDAP))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
if (c != null)
{
buffer.append("connectionID=");
buffer.append(c.getConnectionID());
final String connectionName = c.getConnectionName();
if (connectionName != null)
{
buffer.append(" connectionName=\"");
buffer.append(connectionName);
buffer.append('"');
}
final String connectionPoolName = c.getConnectionPoolName();
if (connectionPoolName != null)
{
buffer.append(" connectionPoolName=\"");
buffer.append(connectionPoolName);
buffer.append('"');
}
buffer.append(" connectedTo=\"");
buffer.append(c.getConnectedAddress());
buffer.append(':');
buffer.append(c.getConnectedPort());
buffer.append("\" ");
}
buffer.append("readLDAPResult=\"");
r.toString(buffer);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about the provided ASN.1 element to be written,
* if appropriate. If it is to be logged, then it will be sent to the
* underlying logger using the {@code INFO} level.
*
* @param e The ASN.1 element for which debug information should be written.
*/
public static void debugASN1Write(final ASN1Element e)
{
if (debugEnabled && debugTypes.contains(DebugType.ASN1))
{
debugASN1Write(Level.INFO, e);
}
}
/**
* Writes debug information about the provided ASN.1 element to be written,
* if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param e The ASN.1 element for which debug information should be written.
*/
public static void debugASN1Write(final Level l, final ASN1Element e)
{
if (debugEnabled && debugTypes.contains(DebugType.ASN1))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("writingASN1Element=\"");
e.toString(buffer);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about the provided ASN.1 element to be written,
* if appropriate. If it is to be logged, then it will be sent to the
* underlying logger using the {@code INFO} level.
*
* @param b The ASN.1 buffer with the information to be written.
*/
public static void debugASN1Write(final ASN1Buffer b)
{
if (debugEnabled && debugTypes.contains(DebugType.ASN1))
{
debugASN1Write(Level.INFO, b);
}
}
/**
* Writes debug information about the provided ASN.1 element to be written,
* if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param b The ASN1Buffer with the information to be written.
*/
public static void debugASN1Write(final Level l, final ASN1Buffer b)
{
if (debugEnabled && debugTypes.contains(DebugType.ASN1))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("writingASN1Element=\"");
StaticUtils.toHex(b.toByteArray(), buffer);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about the provided ASN.1 element that was read, if
* appropriate. If it is to be logged, then it will be sent to the underlying
* logger using the {@code INFO} level.
*
* @param e The ASN.1 element for which debug information should be written.
*/
public static void debugASN1Read(final ASN1Element e)
{
if (debugEnabled && debugTypes.contains(DebugType.ASN1))
{
debugASN1Read(Level.INFO, e);
}
}
/**
* Writes debug information about the provided ASN.1 element that was read, if
* appropriate.
*
* @param l The log level that should be used for the debug information.
* @param e The ASN.1 element for which debug information should be written.
*/
public static void debugASN1Read(final Level l, final ASN1Element e)
{
if (debugEnabled && debugTypes.contains(DebugType.ASN1))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("readASN1Element=\"");
e.toString(buffer);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about the provided ASN.1 element that was read, if
* appropriate.
*
* @param l The log level that should be used for the debug
* information.
* @param dataType A string representation of the data type for the data
* that was read.
* @param berType The BER type for the element that was read.
* @param length The number of bytes in the value of the element that was
* read.
* @param value A representation of the value that was read. The debug
* message will include the string representation of this
* value, unless the value is a byte array in which it will
* be a hex representation of the bytes that it contains.
* It may be {@code null} for an ASN.1 null element.
*/
public static void debugASN1Read(final Level l, final String dataType,
final int berType, final int length,
final Object value)
{
if (debugEnabled && debugTypes.contains(DebugType.ASN1))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("readASN1Element=\"dataType='");
buffer.append(dataType);
buffer.append("' berType='");
buffer.append(StaticUtils.toHex((byte) (berType & 0xFF)));
buffer.append("' valueLength=");
buffer.append(length);
if (value != null)
{
buffer.append(" value='");
if (value instanceof byte[])
{
StaticUtils.toHex((byte[]) value, buffer);
}
else
{
buffer.append(value);
}
buffer.append('\'');
}
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about interaction with a connection pool.
*
* @param l The log level that should be used for the debug information.
* @param p The associated connection pool.
* @param c The associated LDAP connection, if appropriate.
* @param m A message with information about the pool interaction.
* @param e An exception to include with the log message, if appropriate.
*/
public static void debugConnectionPool(final Level l,
final AbstractConnectionPool p,
final LDAPConnection c, final String m,
final Throwable e)
{
if (debugEnabled && debugTypes.contains(DebugType.CONNECTION_POOL))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
final String poolName = p.getConnectionPoolName();
buffer.append("connectionPool=\"");
if (poolName == null)
{
buffer.append("{unnamed}");
}
else
{
buffer.append(poolName);
}
buffer.append("\" ");
if (c != null)
{
buffer.append(" connectionID=");
buffer.append(c.getConnectionID());
final String hostPort = c.getHostPort();
if ((hostPort != null) && (! hostPort.isEmpty()))
{
buffer.append(" connectedTo=\"");
buffer.append(hostPort);
buffer.append('"');
}
}
final long currentAvailable = p.getCurrentAvailableConnections();
if (currentAvailable >= 0)
{
buffer.append(" currentAvailableConnections=");
buffer.append(currentAvailable);
}
final long maxAvailable = p.getMaximumAvailableConnections();
if (maxAvailable >= 0)
{
buffer.append(" maxAvailableConnections=");
buffer.append(maxAvailable);
}
buffer.append(" message=\"");
buffer.append(m);
buffer.append('"');
if (e != null)
{
buffer.append(" exception=\"");
StaticUtils.getStackTrace(e, buffer);
buffer.append('"');
}
logger.log(l, buffer.toString(), e);
}
}
/**
* Writes debug information about the provided LDIF record to be written, if
* if appropriate. If it is to be logged, then it will be sent to the
* underlying logger using the {@code INFO} level.
*
* @param r The LDIF record for which debug information should be written.
*/
public static void debugLDIFWrite(final LDIFRecord r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDIF))
{
debugLDIFWrite(Level.INFO, r);
}
}
/**
* Writes debug information about the provided LDIF record to be written, if
* appropriate.
*
* @param l The log level that should be used for the debug information.
* @param r The LDIF record for which debug information should be written.
*/
public static void debugLDIFWrite(final Level l, final LDIFRecord r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDIF))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("writingLDIFRecord=\"");
r.toString(buffer);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about the provided record read from LDIF, if
* appropriate. If it is to be logged, then it will be sent to the underlying
* logger using the {@code INFO} level.
*
* @param r The LDIF record for which debug information should be written.
*/
public static void debugLDIFRead(final LDIFRecord r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDIF))
{
debugLDIFRead(Level.INFO, r);
}
}
/**
* Writes debug information about the provided record read from LDIF, if
* appropriate.
*
* @param l The log level that should be used for the debug information.
* @param r The LDIF record for which debug information should be written.
*/
public static void debugLDIFRead(final Level l, final LDIFRecord r)
{
if (debugEnabled && debugTypes.contains(DebugType.LDIF))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("readLDIFRecord=\"");
r.toString(buffer);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about monitor entry parsing. If it is to be
* logged, then it will be sent to the underlying logger using the
* {@code FINE} level.
*
* @param e The entry containing the monitor information being parsed.
* @param m The message to be written to the debug logger.
*/
public static void debugMonitor(final Entry e, final String m)
{
if (debugEnabled && debugTypes.contains(DebugType.MONITOR))
{
debugMonitor(Level.FINE, e, m);
}
}
/**
* Writes debug information about monitor entry parsing, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param e The entry containing the monitor information being parsed.
* @param m The message to be written to the debug logger.
*/
public static void debugMonitor(final Level l, final Entry e, final String m)
{
if (debugEnabled && debugTypes.contains(DebugType.MONITOR))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("monitorEntryDN=\"");
buffer.append(e.getDN());
buffer.append("\" message=\"");
buffer.append(m);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes debug information about a coding error detected in the use of the
* LDAP SDK. If it is to be logged, then it will be sent to the underlying
* logger using the {@code SEVERE} level.
*
* @param t The {@code Throwable} object that was created and will be thrown
* as a result of the coding error.
*/
public static void debugCodingError(final Throwable t)
{
if (debugEnabled && debugTypes.contains(DebugType.CODING_ERROR))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, Level.SEVERE);
buffer.append("codingError=\"");
StaticUtils.getStackTrace(t, buffer);
buffer.append('"');
logger.log(Level.SEVERE, buffer.toString());
}
}
/**
* Writes a generic debug message, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param t The debug type to use to determine whether to write the message.
* @param m The message to be written.
*/
public static void debug(final Level l, final DebugType t, final String m)
{
if (debugEnabled && debugTypes.contains(t))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("message=\"");
buffer.append(m);
buffer.append('"');
logger.log(l, buffer.toString());
}
}
/**
* Writes a generic debug message, if appropriate.
*
* @param l The log level that should be used for the debug information.
* @param t The debug type to use to determine whether to write the message.
* @param m The message to be written.
* @param e An exception to include with the log message.
*/
public static void debug(final Level l, final DebugType t, final String m,
final Throwable e)
{
if (debugEnabled && debugTypes.contains(t))
{
final StringBuilder buffer = new StringBuilder();
addCommonHeader(buffer, l);
buffer.append("message=\"");
buffer.append(m);
buffer.append('"');
buffer.append(" exception=\"");
StaticUtils.getStackTrace(e, buffer);
buffer.append('"');
logger.log(l, buffer.toString(), e);
}
}
/**
* Writes common header information to the provided buffer. It will include
* the thread ID, name, and caller stack trace (optional), and it will be
* followed by a trailing space.
*
* @param buffer The buffer to which the information should be appended.
* @param level The log level for the message that will be written.
*/
private static void addCommonHeader(final StringBuilder buffer,
final Level level)
{
buffer.append("level=\"");
buffer.append(level.getName());
buffer.append("\" threadID=");
buffer.append(Thread.currentThread().getId());
buffer.append(" threadName=\"");
buffer.append(Thread.currentThread().getName());
if (includeStackTrace)
{
buffer.append("\" calledFrom=\"");
boolean appended = false;
boolean foundDebug = false;
for (final StackTraceElement e : Thread.currentThread().getStackTrace())
{
final String className = e.getClassName();
if (className.equals(Debug.class.getName()))
{
foundDebug = true;
}
else if (foundDebug)
{
if (appended)
{
buffer.append(" / ");
}
appended = true;
buffer.append(e.getMethodName());
buffer.append('(');
buffer.append(e.getFileName());
final int lineNumber = e.getLineNumber();
if (lineNumber > 0)
{
buffer.append(':');
buffer.append(lineNumber);
}
else if (e.isNativeMethod())
{
buffer.append(":native");
}
buffer.append(')');
}
}
}
buffer.append("\" ldapSDKVersion=\"");
buffer.append(Version.NUMERIC_VERSION_STRING);
buffer.append("\" revision=\"");
buffer.append(Version.REVISION_ID);
buffer.append("\" ");
}
}