391N/A/*
391N/A * CDDL HEADER START
391N/A *
391N/A * The contents of this file are subject to the terms of the
391N/A * Common Development and Distribution License, Version 1.0 only
391N/A * (the "License"). You may not use this file except in compliance
391N/A * with the License.
391N/A *
391N/A * You can obtain a copy of the license at
391N/A * trunk/opends/resource/legal-notices/OpenDS.LICENSE
391N/A * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
391N/A * See the License for the specific language governing permissions
391N/A * and limitations under the License.
391N/A *
391N/A * When distributing Covered Code, include this CDDL HEADER in each
391N/A * file and include the License file at
391N/A * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
391N/A * add the following below this CDDL HEADER, with the fields enclosed
873N/A * by brackets "[]" replaced with your own identifying information:
391N/A * Portions Copyright [yyyy] [name of copyright owner]
391N/A *
391N/A * CDDL HEADER END
391N/A *
391N/A *
3215N/A * Copyright 2006-2008 Sun Microsystems, Inc.
391N/A */
391N/Apackage org.opends.server.util;
2086N/Aimport org.opends.messages.Message;
391N/A
1400N/Aimport static org.opends.server.loggers.debug.DebugLogger.*;
1400N/Aimport org.opends.server.loggers.debug.DebugTracer;
2086N/Aimport org.opends.server.loggers.ErrorLogger;
2086N/A
391N/A/**
391N/A * This utility class provides static methods that make parameter checking
391N/A * easier (e.g. in constructors and setters).
391N/A * In particular the ensureNotNull methods provide an easy way to validate that
391N/A * certain parameters are not null, and the ensureTrue methods provide the
391N/A * ability to check arbitrary boolean conditions.
391N/A * <p>
391N/A * Invocation of these methods should be limited to situations where the only
391N/A * way that they should fail is if there is a defect somewhere in the
391N/A * system (including 3rd-party plugins).
391N/A * <p>
391N/A * You can think of these methods as being similar to <code>assert</code>,
391N/A * but there are some additional advantages:
391N/A * <ul>
391N/A * <li>All failures are logged to the debug and error logs</li>
391N/A * <li>Checks are always enabled (even if asserts are off)</li>
391N/A * <li>This class tracks the number of failures, allowing it to
391N/A * be exposed via monitoring, etc.<li>
391N/A * <li>The unit tests can track unnoticed internal failures and
391N/A * report on them.</li>
391N/A * <li>Developers can catch all Validator failures with a single
391N/A * break point.</li>
391N/A * </ul>
391N/A *
391N/A * In general, you should not worry about the performance impact of calling
391N/A * these methods. Some micro-benchmarking has shown that ensureNotNull can be
391N/A * called 200M times per second on a single CPU laptop. The value of catching
391N/A * defects early will almost always out-weigh any overhead that is introduced.
391N/A * There are a couple of exceptions to this. Any execution overhead that
391N/A * happens before the method is invoked cannot be eliminated, e.g.
391N/A * <code>Validator.ensureTrue(someExpensiveCheck())</code> will always invoke
391N/A * <code>someExpensiveCheck()</code>. When this code is on the critical path,
699N/A * and we do not expect the validation to fail, you can guard the call with
391N/A * an <code>assert</code> because each method returns true, and this code will
391N/A * only be executed when asserts are enabled.
391N/A * <p>
391N/A * These methods are provided primarily to check parameter values for
391N/A * constructors, setters, etc, and when they are used in this way, the javadoc
391N/A * for the method must be updated to reflect what constraints are placed on the
391N/A * parameters (e.g. attributeType cannot be null).
391N/A * <p>
391N/A * Feel free to add any method to this class that makes sense. Be sure to
391N/A * ensure that they don't violate the spirit of this class in that performance
391N/A * is second only to correctness.
391N/A * <p>
391N/A * There are a few issues open for remaining tasks:
391N/A * <ul>
391N/A * <li>757 Validator should expose a way to turn it off</li>
391N/A * <li>758 Validator should provide a way to throttle it's error messages</li>
391N/A * <li>759 Unit tests should always check that no unexpected Validator checks
391N/A * failed</li>
391N/A * </ul>
391N/A */
2095N/A@org.opends.server.types.PublicAPI(
2095N/A stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
2095N/A mayInstantiate=false,
2095N/A mayExtend=false,
2095N/A mayInvoke=true)
391N/Apublic class Validator {
1400N/A /**
1400N/A * The tracer object for the debug logger.
1400N/A */
1400N/A private static final DebugTracer TRACER = getTracer();
1400N/A
391N/A /** This static final variable theoretically allows us to compile out all of
391N/A * these checks. Since all of the code below is guarded with this check,
391N/A * the compiler should eliminate it if ENABLE_CHECKS is false.
391N/A * From doing a little bit of micro-benchmarking, it appears that setting
391N/A * ENABLE_CHECKS=false speeds the code up by about a factor of four, but
391N/A * it's still not the same as not having the invocation in the first place.
391N/A * On a single CPU laptop, I was able to get 200M
391N/A * invocations per second with ENABLE_CHECKS=true, and 350M with
391N/A * ENABLE_CHECKS=false.
391N/A * <p>
391N/A * Setting this to false, will not eliminate any expensive computation
391N/A * done in a parameter list (e.g. some self-check that returns true).*/
391N/A public static final boolean ENABLE_CHECKS = true;
391N/A
391N/A
391N/A
391N/A
391N/A /** A one-based array for parameter descriptions. */
391N/A private static final String[] PARAM_DESCRIPTIONS =
391N/A {"** A ZERO-BASED INDEX IS INVALID **",
391N/A "(1st parameter)",
391N/A "(2nd parameter)",
391N/A "(3rd parameter)",
391N/A "(4th parameter)",
391N/A "(5th parameter)",
391N/A "(6th parameter)",
391N/A "(7th parameter)",
391N/A "(8th parameter)",
391N/A "(9th parameter)",
391N/A "(10th parameter)"};
391N/A
391N/A /** A count of the errors detected by the methods in this class since the
391N/A * last time that resetErrorCount was called. */
391N/A private static long _errorCount = 0;
391N/A
391N/A
391N/A /**
391N/A * This method validates that the specified parameter is not null. It
533N/A * throws an AssertionError if it is null after logging this error.
391N/A * <p>
391N/A * This should be used like an assert, except it is not turned
391N/A * off at runtime. That is, it should only be used in situations where
391N/A * there is a bug in someone's code if param is null.
391N/A *
391N/A * @param param the parameter to validate as non-null.
391N/A * @return true always. This allows this call to be used in an assert
391N/A * statement, which can skip this check and remove all
391N/A * overhead from the calling code. This idiom should only be used when
391N/A * performance testing proves that it is necessary.
391N/A *
533N/A * @throws AssertionError if and only if param is null
391N/A * if assertions are enabled
391N/A */
391N/A public static boolean ensureNotNull(Object param)
533N/A throws AssertionError {
391N/A if (ENABLE_CHECKS) {
2114N/A if (param == null) throwNull("");
391N/A }
391N/A return true;
391N/A }
391N/A
391N/A
391N/A
391N/A /**
391N/A * This method validates that the specified parameters are not null. It
533N/A * throws an AssertionError if one of them are null after logging this error.
533N/A * It's similar to the ensureNotNull(Object) call except it provides the
533N/A * convenience of checking two parameters at once.
391N/A * <p>
391N/A * This should be used like an assert, except it is not turned
391N/A * off at runtime. That is, it should only be used in situations where
391N/A * there is a bug in someone's code if param is null.
391N/A * <p>
391N/A * See the class level javadoc for why we did not use varargs to
391N/A * implement this method.
391N/A *
391N/A * @param param1 the first parameter to validate as non-null.
391N/A * @param param2 the second parameter to validate as non-null.
391N/A * @return true always. This allows this call to be used in an assert
391N/A * statement, which can skip this check and remove all
391N/A * overhead from the calling code. This idiom should only be used when
391N/A * performance testing proves that it is necessary.
391N/A *
533N/A * @throws AssertionError if and only if any of the parameters is null
391N/A */
391N/A public static boolean ensureNotNull(Object param1, Object param2)
533N/A throws AssertionError {
391N/A if (ENABLE_CHECKS) {
2114N/A if (param1 == null) throwNull(PARAM_DESCRIPTIONS[1]);
2114N/A if (param2 == null) throwNull(PARAM_DESCRIPTIONS[2]);
391N/A }
391N/A return true;
391N/A }
391N/A
391N/A
391N/A
391N/A /**
391N/A * This method validates that the specified parameters are not null. It
533N/A * throws an AssertionError if one of them are null after logging this error.
533N/A * It's similar to the ensureNotNull(Object) call except it provides the
533N/A * convenience of checking three parameters at once.
391N/A * <p>
391N/A * This should be used like an assert, except it is not turned
391N/A * off at runtime. That is, it should only be used in situations where
391N/A * there is a bug in someone's code if param is null.
391N/A * <p>
391N/A * See the class level javadoc for why we did not use varargs to
391N/A * implement this method.
391N/A *
391N/A * @param param1 the first parameter to validate as non-null.
391N/A * @param param2 the second parameter to validate as non-null.
391N/A * @param param3 the third parameter to validate as non-null.
391N/A * @return true always. This allows this call to be used in an assert
391N/A * statement, which can skip this check and remove all
391N/A * overhead from the calling code. This idiom should only be used when
391N/A * performance testing proves that it is necessary.
391N/A *
533N/A * @throws AssertionError if and only if one of the parameters is null
391N/A */
391N/A public static boolean ensureNotNull(Object param1, Object param2,
391N/A Object param3)
533N/A throws AssertionError {
391N/A if (ENABLE_CHECKS) {
2114N/A if (param1 == null) throwNull(PARAM_DESCRIPTIONS[1]);
2114N/A if (param2 == null) throwNull(PARAM_DESCRIPTIONS[2]);
2114N/A if (param3 == null) throwNull(PARAM_DESCRIPTIONS[3]);
391N/A }
391N/A return true;
391N/A }
391N/A
391N/A
391N/A
391N/A /**
391N/A * This method validates that the specified parameters are not null. It
533N/A * throws an AssertionError if one of them are null after logging this error.
533N/A * It's similar to the ensureNotNull(Object) call except it provides the
533N/A * convenience of checking four parameters at once.
391N/A * <p>
391N/A * This should be used like an assert, except it is not turned
391N/A * off at runtime. That is, it should only be used in situations where
391N/A * there is a bug in someone's code if param is null.
391N/A * <p>
391N/A * See the class level javadoc for why we did not use varargs to
391N/A * implement this method.
391N/A *
391N/A * @param param1 the first parameter to validate as non-null.
391N/A * @param param2 the second parameter to validate as non-null.
391N/A * @param param3 the third parameter to validate as non-null.
391N/A * @param param4 the fourth parameter to validate as non-null.
391N/A * @return true always. This allows this call to be used in an assert
391N/A * statement, which can skip this check and remove all
391N/A * overhead from the calling code. This idiom should only be used when
391N/A * performance testing proves that it is necessary.
391N/A *
533N/A * @throws AssertionError if and only if one of the parameters is null
391N/A */
391N/A public static boolean ensureNotNull(Object param1, Object param2,
391N/A Object param3, Object param4)
533N/A throws AssertionError {
391N/A if (ENABLE_CHECKS) {
2114N/A if (param1 == null) throwNull(PARAM_DESCRIPTIONS[1]);
2114N/A if (param2 == null) throwNull(PARAM_DESCRIPTIONS[2]);
2114N/A if (param3 == null) throwNull(PARAM_DESCRIPTIONS[3]);
2114N/A if (param4 == null) throwNull(PARAM_DESCRIPTIONS[4]);
391N/A }
391N/A return true;
391N/A }
391N/A
391N/A
391N/A /**
391N/A * This method validates that the specified parameter is true. It
533N/A * throws an AssertionError if it is not true.
391N/A * <p>
391N/A * This should be used like an assert, except it is not turned
391N/A * off at runtime. That is, it should only be used in situations where
391N/A * there is a bug in someone's code if param is null. The other advantage of
391N/A * using this method instead of an assert is that it logs the error to the
391N/A * debug and error logs.
391N/A *
391N/A * @param condition the condition that must be true.
391N/A * @return true always. This allows this call to be used in an assert
391N/A * statement, which can skip this check and remove all
391N/A * overhead from the calling code. This idiom should only be used when
391N/A * performance testing proves that it is necessary.
391N/A *
533N/A * @throws AssertionError if condition is false
391N/A */
391N/A public static boolean ensureTrue(boolean condition)
533N/A throws AssertionError {
391N/A if (ENABLE_CHECKS) {
391N/A if (!condition) {
2114N/A ensureTrue(condition, "");
391N/A }
391N/A }
391N/A return true;
391N/A }
391N/A
391N/A
391N/A
391N/A /**
391N/A * This method validates that the specified parameter is true. It
533N/A * throws an AssertionError if it is not true. The supplied message is
533N/A * included in the error message.
391N/A * <p>
391N/A * This should be used like an assert, except it is not turned
391N/A * off at runtime. That is, it should only be used in situations where
391N/A * there is a bug in someone's code if param is null. The other advantage of
391N/A * using this method instead of an assert is that it logs the error to the
391N/A * debug and error logs.
391N/A *
391N/A * @param condition the condition that must be true.
391N/A * @param message the textual message to include in the error message.
391N/A * @return true always. This allows this call to be used in an assert
391N/A * statement, which can skip this check and remove all
391N/A * overhead from the calling code. This idiom should only be used when
391N/A * performance testing proves that it is necessary.
391N/A *
533N/A * @throws AssertionError if condition is false
391N/A */
2114N/A public static boolean ensureTrue(boolean condition, String message)
533N/A throws AssertionError {
391N/A if (ENABLE_CHECKS) {
391N/A if (!condition) {
2114N/A StringBuilder mb = new StringBuilder();
2086N/A mb.append("The specified condition must be true. ");
2086N/A mb.append(message);
2114N/A String fullString = generateLineSpecificErrorString(mb.toString());
391N/A
2114N/A logError(fullString);
391N/A
2114N/A throw new AssertionError(fullString);
391N/A }
391N/A }
391N/A return true;
391N/A }
391N/A
391N/A ////////////////////////////////////////////////////////////////////////////
391N/A //
391N/A // ERROR COUNT
391N/A //
391N/A ////////////////////////////////////////////////////////////////////////////
391N/A
391N/A
391N/A /**
391N/A * Returns the number of errors that this class has detected since the
391N/A * system started or the last time that resetErrorCount() was called.
391N/A * <p>
391N/A * This could be useful in the unit tests to validate that no background
391N/A * errors occurred during a test. It could also be exposed by the monitoring
391N/A * framekwork.
391N/A *
391N/A * @return the number of errors detected by this class since the error count
391N/A * was last reset.
391N/A */
391N/A public static synchronized long getErrorCount() {
391N/A return _errorCount;
391N/A }
391N/A
391N/A
391N/A /**
391N/A * Resets the error count to zero.
391N/A */
391N/A public static synchronized void resetErrorCount() {
391N/A _errorCount = 0;
391N/A }
391N/A
391N/A
391N/A private static synchronized void incrementErrorCount() {
391N/A _errorCount++;
391N/A }
391N/A
391N/A
391N/A ////////////////////////////////////////////////////////////////////////////
391N/A //
391N/A // PRIVATE
391N/A //
391N/A ////////////////////////////////////////////////////////////////////////////
391N/A
391N/A
2114N/A private static String generateLineSpecificErrorString(String message) {
2114N/A StringBuilder mb = new StringBuilder();
2086N/A mb.append(message);
2086N/A mb.append(" The error occurred at ");
2086N/A mb.append(getOriginalCallerLineInfo());
2114N/A return mb.toString();
391N/A }
391N/A
391N/A
2114N/A private static void throwNull(String message)
533N/A throws AssertionError {
2114N/A StringBuilder mb = new StringBuilder();
2086N/A mb.append("The specified parameter must not be null. ");
2086N/A mb.append(message);
2114N/A String fullString = generateLineSpecificErrorString(mb.toString());
391N/A
2114N/A logError(fullString);
391N/A
2114N/A throw new AssertionError(fullString);
391N/A }
391N/A
391N/A
391N/A
2114N/A private static void logError(String message) {
391N/A incrementErrorCount();
391N/A
2114N/A StringBuilder mb = new StringBuilder();
2086N/A mb.append(message);
2086N/A mb.append(ServerConstants.EOL);
2086N/A mb.append(getCallingStack());
2114N/A String messageWithStack = mb.toString();
391N/A
391N/A // Log to the debug log.
868N/A if (debugEnabled())
868N/A {
2086N/A TRACER.debugError(messageWithStack.toString());
868N/A }
391N/A
391N/A // Log to the error log.
2114N/A ErrorLogger.logError(Message.raw(messageWithStack));
391N/A }
391N/A
391N/A
391N/A /*
391N/A * @return a String representation of the line that called the
391N/A * Validator method.
391N/A */
391N/A private static String getOriginalCallerLineInfo() {
391N/A StackTraceElement stackElements[] = Thread.currentThread().getStackTrace();
391N/A int callerIndex = getOriginalCallerStackIndex(stackElements);
391N/A return stackElements[callerIndex].toString();
391N/A }
391N/A
391N/A
391N/A /*
391N/A * @return a stack trace rooted at the line that called the first
391N/A * Validator method.
391N/A */
391N/A private static String getCallingStack() {
391N/A StackTraceElement stackElements[] = Thread.currentThread().getStackTrace();
391N/A int callerIndex = getOriginalCallerStackIndex(stackElements);
391N/A
391N/A StringBuilder buffer = new StringBuilder();
391N/A for (int i = callerIndex; i < stackElements.length; i++) {
391N/A StackTraceElement stackElement = stackElements[i];
391N/A buffer.append(stackElement).append(ServerConstants.EOL);
391N/A }
391N/A
391N/A return buffer.toString();
391N/A }
391N/A
391N/A
391N/A /*
391N/A * @return the index in the supplied stack trace of the first non-Validator
391N/A * method.
391N/A */
391N/A private static int getOriginalCallerStackIndex(StackTraceElement stack[]) {
391N/A // Go up the stack until we find who called the first Validator method.
391N/A StackTraceElement element = null;
391N/A int i;
391N/A for (i = 0; i < stack.length; i++) {
391N/A element = stack[i];
391N/A // The stack trace of this thread looks like
391N/A // java.lang.Thread.dumpThreads(Native Method)
391N/A // java.lang.Thread.getStackTrace(Thread.java:1383)
391N/A // org.opends.server.util.Validator.getOriginalCallerLineInfo...
391N/A // ...
391N/A // original caller <---- this is what we want to return
391N/A // more stack
391N/A if (!element.getClassName().equals(Validator.class.getName()) &&
391N/A !element.getClassName().equals(Thread.class.getName())) {
391N/A break;
391N/A }
391N/A }
391N/A
391N/A return i;
391N/A }
391N/A}