com.tangosol.util.Base Maven / Gradle / Ivy
Show all versions of coherence Show documentation
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/
package com.tangosol.util;
import com.oracle.coherence.common.base.Assertions;
import com.oracle.coherence.common.base.Blocking;
import com.oracle.coherence.common.base.Classes;
import com.oracle.coherence.common.base.Exceptions;
import com.oracle.coherence.common.base.Formatting;
import com.oracle.coherence.common.base.Hasher;
import com.oracle.coherence.common.base.HashHelper;
import com.oracle.coherence.common.base.Logger;
import com.oracle.coherence.common.base.Objects;
import com.oracle.coherence.common.base.Randoms;
import com.oracle.coherence.common.base.Reads;
import com.oracle.coherence.common.base.StackTrace;
import com.oracle.coherence.common.base.TimeHelper;
import com.oracle.coherence.common.util.CommonMonitor;
import com.tangosol.coherence.config.Config;
import com.tangosol.net.CacheFactory;
import java.io.CharArrayWriter;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.rmi.RemoteException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.TimeZone;
/**
* Base class for providing standard functionality.
*
* @author cp 2000.08.02
*/
@SuppressWarnings({"unused", "deprecation"})
public abstract class Base
{
// ----- debugging support: expression evaluation ----------------------
/**
* Display the value of a boolean expression.
*
* @param fVal the boolean value
*/
public static void trace(boolean fVal)
{
traceImpl(String.valueOf(fVal));
}
/**
* Display the value of a char expression.
*
* @param chVal the char value
*/
public static void trace(char chVal)
{
traceImpl(String.valueOf(chVal));
}
/**
* Display the value of an int expression.
*
* @param nVal the int value
*/
public static void trace(int nVal)
{
traceImpl(String.valueOf(nVal));
}
/**
* Display the value of a long expression.
*
* @param lVal the long value
*/
public static void trace(long lVal)
{
traceImpl(String.valueOf(lVal));
}
/**
* Display the value of a float expression.
*
* @param flVal the float value
*/
public static void trace(float flVal)
{
traceImpl(String.valueOf(flVal));
}
/**
* Display the value of a double expression.
*
* @param dflVal the double value
*/
public static void trace(double dflVal)
{
traceImpl(String.valueOf(dflVal));
}
/**
* Display the value of a byte array expression.
*
* @param ab the byte array value
*/
public static void trace(byte[] ab)
{
if (ab == null)
{
traceImpl(null);
}
else
{
traceImpl("length=" + ab.length + ", binary=" + toHexEscape(ab));
}
}
/**
* Display the value of a String expression.
*
* @param sVal the String value
*/
public static void trace(String sVal)
{
traceImpl(sVal == null ? "null" : toQuotedStringEscape(sVal));
}
/**
* Display the value of an Object expression.
*
* @param oVal the Object value
*/
public static void trace(Object oVal)
{
traceImpl(String.valueOf(oVal));
}
/**
* Internal implementation for trace methods.
*/
private static void traceImpl(String sVal)
{
String sExpr = StackTrace.getExpression("trace");
out((sExpr == null ? "?" : sExpr) + '=' + (sVal == null ? "null" : sVal));
}
// ----- assertion support ----------------------------------------------
/**
* Definite assertion failure.
*
* @return null
*/
public static RuntimeException azzert()
{
return Assertions.azzert();
}
/**
* Test an assertion.
*
* @param f the boolean to be checked
*/
public static void azzert(boolean f)
{
Assertions.azzert(f);
}
/**
* Test an assertion, and print the specified message if the assertion
* fails.
*
* @param f the boolean to be checked
* @param s the assertion message
*/
public static void azzert(boolean f, String s)
{
Assertions.azzert(f, s);
}
/**
* Throw an assertion exception.
*
* @param sMsg the assertion message
*/
public static void azzertFailed(String sMsg)
{
Assertions.azzertFailed(sMsg);
}
// ----- exception support ----------------------------------------------
/**
* Convert the passed exception to a RuntimeException if necessary.
*
* @apiNote We can't use the {@link Exceptions#ensureRuntimeException(Throwable)}
* because we want to return a {@link WrapperException} for Coherence.
*
* @param e any Throwable object
*
* @return a RuntimeException
*/
public static RuntimeException ensureRuntimeException(Throwable e)
{
return ensureRuntimeException(e, null);
}
/**
* Convert the passed exception to a RuntimeException if necessary.
*
* @param e any Throwable object
* @param s an additional description
*
* @return a RuntimeException
*
* @apiNote We can't use the {@link Exceptions#ensureRuntimeException(Throwable, String)}
* because we want to return a {@link WrapperException} for Coherence.
*/
public static RuntimeException ensureRuntimeException(Throwable e, String s)
{
if (e instanceof RuntimeException && s == null)
{
return (RuntimeException) e;
}
else
{
return new WrapperException(e, s);
}
}
/**
* Unwind the wrapper (runtime) exception to extract the original
*
* @apiNote We can't use the {@link Exceptions#getOriginalException(RuntimeException)}
* because we want to return a {@link WrapperException} for Coherence.
*
* @param e Runtime exception (wrapper)
*
* @return an original wrapped exception
*/
public static Throwable getOriginalException(RuntimeException e)
{
Throwable t = e;
while (true)
{
if (t instanceof WrapperException)
{
t = ((WrapperException) t).getOriginalException();
}
else if (t instanceof RemoteException)
{
t = ((RemoteException) t).detail;
}
// we do not want to have runtime dependency on j2ee classes
else if (t.getClass().getName().equals("javax.ejb.EJBException"))
{
try
{
t = (Throwable) ClassHelper.invoke(t,
"getCausedByException", ClassHelper.VOID);
}
catch (Exception x)
{
return t;
}
}
else
{
return t;
}
}
}
// ----- printed output support -----------------------------------------
/**
* Prints a blank line.
*/
public static void out()
{
s_out.println();
}
/**
* Prints the passed Object.
*
* @param o the Object to print.
*/
public static void out(Object o)
{
s_out.println(o);
}
/**
* Prints the passed String value.
*
* @param s the String to print.
*/
public static void out(String s)
{
s_out.println(s);
}
/**
* Prints the passed class information.
*
* @param clz the class object to print.
*/
public static void out(Class> clz)
{
s_out.println(Classes.toString(clz));
}
/**
* Prints the passed exception information.
*
* @param e the Throwable object to print.
*/
public static void out(Throwable e)
{
s_out.println(printStackTrace(e));
}
/**
* Prints a blank line to the trace Writer.
*/
public static void err()
{
s_err.println();
}
/**
* Prints the passed Object to the trace Writer.
*
* @param o the Object to print.
*/
public static void err(Object o)
{
s_err.println(o);
}
/**
* Prints the passed String value to the trace Writer.
*
* @param s the String to print.
*/
public static void err(String s)
{
s_err.println(s);
}
/**
* Prints the passed class information to the trace Writer.
*
* @param clz the class object to print.
*/
public static void err(Class> clz)
{
s_err.println(Classes.toString(clz));
}
/**
* Prints the passed exception information to the trace Writer.
*
* @param e the Throwable object to print.
*/
public static void err(Throwable e)
{
s_err.println(printStackTrace(e));
}
/**
* Prints a blank line to the log.
*/
public static void log()
{
s_log.println();
if (s_fEchoLog)
{
s_out.println();
}
}
/**
* Prints the passed Object to the log.
*
* @param o the Object to print
*/
public static void log(Object o)
{
log(String.valueOf(o));
}
/**
* Prints the passed String value to the log.
*
* @param s the String to print
*/
public static void log(String s)
{
s_log.println(s);
if (s_fEchoLog)
{
s_out.println(s);
}
}
/**
* Prints the passed class information to the log.
*
* @param clz the class object to print
*/
public static void log(Class> clz)
{
log(Classes.toString(clz));
}
/**
* Prints the passed exception information to the log.
*
* @param e the Throwable object to print
*/
public static void log(Throwable e)
{
String s = printStackTrace(e);
s_log.println(s);
if (s_fEchoLog)
{
s_out.println(s);
}
}
// ----- class loader support --------------------------------------------
/**
* Obtain a non-null ClassLoader.
*
* @param loader a ClassLoader (may be null)
*
* @return the passed ClassLoader (if not null), or the ContextClassLoader
*/
public static ClassLoader ensureClassLoader(ClassLoader loader)
{
return Classes.ensureClassLoader(loader);
}
/**
* Try to determine the ClassLoader that supports the current context.
*
* @return a ClassLoader to use for the current context
*/
public static ClassLoader getContextClassLoader()
{
return Classes.getContextClassLoader();
}
/**
* Try to determine the ClassLoader that supports the current context.
*
* @param o the calling object, or any object out of the application
* that is requesting the class loader
*
* @return a ClassLoader to use for the current context
*/
public static ClassLoader getContextClassLoader(Object o)
{
return Classes.getContextClassLoader(o);
}
// ----- stack trace support --------------------------------------------
/**
* Get the StackFrame information for the caller of the current method.
*
* @return the StackFrame information for the caller of the current method
*/
public static StackTrace.StackFrame getCallerStackFrame()
{
return StackTrace.getCallerStackFrame();
}
/**
* Get the StackFrame information for the current method.
*
* @return the StackFrame information for the current method
*/
public static StackTrace.StackFrame getStackFrame()
{
return StackTrace.getStackFrame();
}
/**
* Iterate the StackFrame information for all callers, going from the
* inside outwards, and starting with the caller of this method.
*
* @return an Iterator of StackFrames
*/
public static StackTrace.StackFrame[] getStackFrames()
{
return StackTrace.getStackFrames();
}
/**
* Build a stack trace for the current thread.
*
* @return a String containing a printable stack trace
*/
public static String getStackTrace()
{
return StackTrace.getStackTrace();
}
/**
* Build a stack trace for the passed exception that does not include
* the exception description itself.
*
* @param e a Throwable object that contains stack trace information
*
* @return a String containing a printable stack trace
*/
public static String getStackTrace(Throwable e)
{
return StackTrace.getStackTrace(e);
}
/**
* Print stack trace for running thread.
*
* @param t thread
*
* @return thread stack trace or empty string if thread is not running
*
* @since Coherence 12.2.1.4.16
*/
public static String getStackTrace(Thread t)
{
return StackTrace.getStackTrace(t);
}
/**
* Extract a throwable's message, and all causal messages.
*
* @param t the throwable
* @param sDelim the delimiter to include between messages
*
* @return the concatenated messages
*/
public static String getDeepMessage(Throwable t, String sDelim)
{
return StackTrace.getDeepMessage(t, sDelim);
}
/**
* Build a stack trace for the passed exception.
*
* @param e a Throwable object that contains stack trace information
*
* @return a String containing a printable stack trace
*/
public static String printStackTrace(Throwable e)
{
return StackTrace.printStackTrace(e);
}
/**
* Ensure the specified Number is a BigDecimal value or convert it into a
* new BigDecimal object.
*
* @param num a Number object
*
* @return a BigDecimal object that is equal to the passed in Number
*/
public static BigDecimal ensureBigDecimal(Number num)
{
return StackTrace.ensureBigDecimal(num);
}
// ----- thread factory support -----------------------------------------
/**
* Create a Thread with the specified group, runnable, and name, using
* the configured ThreadFactory, as specified by the
* tangosol.coherence.threadfactory system property.
*
* @param group (optional) the thread's thread group
* @param runnable (optional) the thread's runnable
* @param sName (optional) the thread's name
*
* @return a new thread using the specified parameters
*/
public static Thread makeThread(ThreadGroup group, Runnable runnable,
String sName)
{
ThreadFactory factory = s_threadFactory;
if (factory == null)
{
return sName == null ? new Thread(group, runnable)
: new Thread(group, runnable, sName);
}
else
{
return factory.makeThread(group, runnable, sName);
}
}
/**
* Return the configured thread factory.
*
* @return the configured thread factory, or null if none has been configured
*/
public static ThreadFactory getThreadFactory()
{
return s_threadFactory;
}
/**
* Instantiate the configured thread factory.
*
* @return the configured thread factory, or null if none has been configured
*/
private static ThreadFactory instantiateThreadFactory()
{
String sFactory = AccessController.doPrivileged(
(PrivilegedAction) () -> Config.getProperty("coherence.threadfactory"));
if (sFactory == null)
{
return null;
}
try
{
return (ThreadFactory) Class.forName(sFactory).newInstance();
}
catch (Exception e)
{
throw ensureRuntimeException(e);
}
}
// ----- thread sleep/wait support --------------------------------------
/**
* Convenience method for {@link java.lang.Thread#sleep(long)}.
*
* If the thread is interrupted before the sleep time expires, a
* RuntimeException is thrown and the thread's interrupt state is set.
*
* @param cMillis the maximum time to wait in milliseconds
*/
public static void sleep(long cMillis)
{
try
{
while (cMillis > 0)
{
long lStart = getSafeTimeMillis();
Blocking.sleep(cMillis);
// safe time ensures time only moves forward
cMillis -= (getSafeTimeMillis() - lStart);
}
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
throw ensureRuntimeException(e);
}
}
/**
* Convenience method for {@link java.lang.Object#wait(long)}.
*
* If the thread is interrupted before being notified or the wait time
* expires, a RuntimeException is thrown and the thread's interrupt state is
* set.
*
* @param o the Object to wait for
* @param cMillis the maximum time to wait in milliseconds
*/
public static void wait(Object o, long cMillis)
{
try
{
Blocking.wait(o, cMillis);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
throw ensureRuntimeException(e);
}
}
// ----- common monitor support -----------------------------------------
/**
* Return the common monitor associated with the specified integer value.
*
* @param i the common monitor identifier
*
* @return the associated monitor
*
* @see CommonMonitor
*/
public static CommonMonitor getCommonMonitor(int i)
{
return CommonMonitor.getCommonMonitor(i);
}
/**
* Return the common monitor associated with the specified long value.
*
* @param l the common monitor identifier
*
* @return the associated monitor
*
* @see CommonMonitor
*/
public static CommonMonitor getCommonMonitor(long l)
{
return CommonMonitor.getCommonMonitor(l);
}
/**
* Return the common monitor associated with the specified object based on
* its identity hashCode.
*
* @param o the object to obtain a common monitor for
*
* @return the associated monitor
*
* @see CommonMonitor
*/
public static CommonMonitor getCommonMonitor(Object o)
{
return CommonMonitor.getCommonMonitor(o);
}
// ----- class formatting support ---------------------------------------
/**
* Formats Class information for debug output purposes.
*
* @param clz the Class to print information for
*
* @return a String describing the Class in detail
*/
public static String toString(Class> clz)
{
return Classes.toString(clz);
}
// ----- formatting support: decimal values -----------------------------
/**
* Returns true if the passed character is a decimal digit.
*
* @param ch The character to check
*
* @return {@code true} if the passed character is a decimal digit
*/
public static boolean isDecimal(char ch)
{
return Formatting.isDecimal(ch);
}
/**
* Returns the integer value of a decimal digit.
*
* @param ch The character to convert
*
* @return the integer value of a decimal digit
*/
public static int decimalValue(char ch)
{
return Formatting.decimalValue(ch);
}
/**
* Calculate the number of decimal digits needed to display the passed
* value.
*
* @param n the value
*
* @return the number of decimal digits needed to display the value
*/
public static int getMaxDecDigits(int n)
{
return Formatting.getMaxDecDigits(n);
}
/**
* Format the passed non-negative integer as a fixed-length decimal string.
*
* @param n the value
* @param cDigits the length of the resulting decimal string
*
* @return the decimal value formatted to the specified length string
*/
public static String toDecString(int n, int cDigits)
{
return Formatting.toDecString(n, cDigits);
}
/**
* Return the smallest value that is not less than the first argument and
* is a multiple of the second argument. Effectively rounds the first
* argument up to a multiple of the second.
*
* @param lMin the smallest value to return
* @param lMultiple the return value will be a multiple of this argument
*
* @return the smallest multiple of the second argument that is not less
* than the first
*/
public static long pad(long lMin, long lMultiple)
{
return Formatting.pad(lMin, lMultiple);
}
// ----- formatting support: octal values -------------------------------
/**
* Returns true if the passed character is an octal digit.
*
* @param ch The character to check
*
* @return {@code true} if the passed character is an octal digit
*/
public static boolean isOctal(char ch)
{
return Formatting.isOctal(ch);
}
/**
* Returns the integer value of an octal digit.
*
* @param ch The character to convert
*
* @return the integer value of an octal digit
*/
public static int octalValue(char ch)
{
return Formatting.octalValue(ch);
}
// ----- formatting support: hex values ---------------------------------
/**
* Returns true if the passed character is a hexadecimal digit.
*
* @param ch The character to check
*
* @return {@code true} if the passed character is a hexadecimal digit
*/
public static boolean isHex(char ch)
{
return Formatting.isHex(ch);
}
/**
* Returns the integer value of a hexadecimal digit.
*
* @param ch The character to convert
*
* @return the integer value
*/
public static int hexValue(char ch)
{
return Formatting.hexValue(ch);
}
/**
* Calculate the number of hex digits needed to display the passed value.
*
* @param n the value
*
* @return the number of hex digits needed to display the value
*/
public static int getMaxHexDigits(int n)
{
return Formatting.getMaxHexDigits(n);
}
/**
* Format the passed integer as a fixed-length hex string.
*
* @param n the value
* @param cDigits the length of the resulting hex string
*
* @return the hex value formatted to the specified length string
*/
public static String toHexString(int n, int cDigits)
{
return Formatting.toHexString(n, cDigits);
}
/**
* Convert a byte to the hex sequence of 2 hex digits.
*
* @param b the byte
*
* @return the hex sequence
*/
public static String toHex(int b)
{
return Formatting.toHex(b);
}
/**
* Convert a byte array to the hex sequence of 2 hex digits per byte.
*
* This is a replacement for Text.toString(char[]).
*
* @param ab the byte array
*
* @return the hex sequence
*/
public static String toHex(byte[] ab)
{
return Formatting.toHex(ab);
}
/**
* Convert a byte to a hex sequence of '0' + 'x' + 2 hex digits.
*
* @param b the byte
*
* @return the hex sequence
*/
public static String toHexEscape(byte b)
{
return Formatting.toHexEscape(b);
}
/**
* Convert a byte array to a hex sequence of '0' + 'x' + 2 hex digits
* per byte.
*
* @param ab the byte array
*
* @return the hex sequence
*/
public static String toHexEscape(byte[] ab)
{
return Formatting.toHexEscape(ab);
}
/**
* Convert a byte array to a hex sequence of '0' + 'x' + 2 hex digits
* per byte.
*
* @param ab the byte array
* @param of the offset into array
* @param cb the number of bytes to convert
*
* @return the hex sequence
*/
public static String toHexEscape(byte[] ab, int of, int cb)
{
return Formatting.toHexEscape(ab, of, cb);
}
/**
* Convert a ByteSequence to a hex sequence of '0' + 'x' + 2 hex digits
* per byte.
*
* @param seq the ByteSequence
* @param of the offset into the byte sequence
* @param cb the number of bytes to convert
*
* @return the hex sequence
*
* @since Coherence 3.7
*/
public static String toHexEscape(ByteSequence seq, int of, int cb)
{
return Formatting.toHexEscape(seq, of, cb);
}
/**
* Convert a byte array to a hex dump.
*
* This is a replacement for Text.toString(byte[] ab, int cBytesPerLine).
*
* @param ab the byte array to format as a hex string
* @param cBytesPerLine the number of bytes to display on a line
*
* @return a multi-line hex dump
*/
public static String toHexDump(byte[] ab, int cBytesPerLine)
{
return Formatting.toHexDump(ab, cBytesPerLine);
}
/**
* Parse the passed String of hexadecimal characters into a binary
* value. This implementation allows the passed String to be prefixed
* with "0x".
*
* @param s the hex String to evaluate
*
* @return the byte array value of the passed hex String
*/
public static byte[] parseHex(String s)
{
return Formatting.parseHex(s);
}
/**
* Return the integer value of a hexadecimal digit.
*
* @param ch the hex character to evaluate
*
* @return the integer value of the passed hex character
*/
public static int parseHex(char ch)
{
return Formatting.parseHex(ch);
}
// ----- formatting support: double -------------------------------------
/**
* Format a double value as a String.
*
* @param dfl a double value
* @param cMinDigits the minimum number of digits of precision to display
*
* @return the double value formatted as a String
*/
public static String toString(double dfl, int cMinDigits)
{
return Formatting.toString(dfl, cMinDigits);
}
// ----- formatting support: character/String ---------------------------
/**
* Format a Unicode character to the Unicode escape sequence of '\'
* + 'u' + 4 hex digits.
*
* @param ch the character
*
* @return the Unicode escape sequence
*/
public static String toUnicodeEscape(char ch)
{
return Formatting.toUnicodeEscape(ch);
}
/**
* Format a char to a printable escape if necessary.
*
* @param ch the char
*
* @return a printable String representing the passed char
*/
public static String toCharEscape(char ch)
{
return Formatting.toCharEscape(ch);
}
/**
* Format a char to a printable escape if necessary as it would
* appear (quoted) in Java source code.
*
* This is a replacement for Text.printableChar().
*
* @param ch the character
*
* @return a printable String in single quotes representing the
* passed char
*/
public static String toQuotedCharEscape(char ch)
{
return Formatting.toQuotedCharEscape(ch);
}
/**
* Format a String escaping characters as necessary.
*
* @param s the String
*
* @return a printable String representing the passed String
*/
public static String toStringEscape(String s)
{
return Formatting.toStringEscape(s);
}
/**
* Format a String as it would appear (quoted) in Java source code,
* escaping characters as necessary.
*
* This is a replacement for Text.printableString().
*
* @param s the String
*
* @return a printable String in double quotes representing the
* passed String
*/
public static String toQuotedStringEscape(String s)
{
return Formatting.toQuotedStringEscape(s);
}
/**
* Format a char to a printable escape if necessary, putting the result
* into the passed array. The array must be large enough to accept six
* characters.
*
* @param ch the character to format
* @param ach the array of characters to format into
* @param of the offset in the array to format at
*
* @return the number of characters used to format the char
*/
public static int escape(char ch, char[] ach, int of)
{
return Formatting.escape(ch, ach, of);
}
/**
* Escapes the string for SQL.
*
* @param s the String to escape
*
* @return the string quoted for SQL and escaped as necessary
*/
public static String toSqlString(String s)
{
return Formatting.toSqlString(s);
}
/**
* Indent the passed multi-line string.
*
* @param sText the string to indent
* @param sIndent a string used to indent each line
*
* @return the string, indented
*/
public static String indentString(String sText, String sIndent)
{
return Formatting.indentString(sText, sIndent);
}
/**
* Textually indent the passed multi-line string.
*
* @param sText the string to indent
* @param sIndent a string used to indent each line
* @param fFirstLine true indents all lines;
* false indents all but the first
*
* @return the string, indented
*/
public static String indentString(String sText, String sIndent, boolean fFirstLine)
{
return Formatting.indentString(sText, sIndent, fFirstLine);
}
/**
* Breaks the specified string into a multi-line string.
*
* @param sText the string to break
* @param nWidth the max width of resulting lines (including the indent)
* @param sIndent a string used to indent each line
*
* @return the string, broken and indented
*/
public static String breakLines(String sText, int nWidth, String sIndent)
{
return Formatting.breakLines(sText, nWidth, sIndent);
}
/**
* Breaks the specified string into a multi-line string.
*
* @param sText the string to break
* @param nWidth the max width of resulting lines (including the
* indent)
* @param sIndent a string used to indent each line
* @param fFirstLine if true indents all lines;
* otherwise indents all but the first
*
* @return the string, broken and indented
*/
public static String breakLines(String sText, int nWidth, String sIndent, boolean fFirstLine)
{
return Formatting.breakLines(sText, nWidth, sIndent, fFirstLine);
}
/**
* Create a String of the specified length containing the specified
* character.
*
* @param ch the character to fill the String with
* @param cch the length of the String
*
* @return a String containing the character <ch> repeated <cch> times
*/
public static String dup(char ch, int cch)
{
return Formatting.dup(ch, cch);
}
/**
* Create a String which is a duplicate of the specified number of the
* passed String.
*
* @param s the String to fill the new String with
* @param c the number of duplicates to put into the new String
*
* @return a String containing the String s repeated c
* times
*/
public static String dup(String s, int c)
{
return Formatting.dup(s, c);
}
/**
* Replace all occurrences of the specified substring in the specified
* string.
*
* @param sText string to change
* @param sFrom pattern to change from
* @param sTo pattern to change to
*
* @return modified string
*/
public static String replace(String sText, String sFrom, String sTo)
{
return Formatting.replace(sText, sFrom, sTo);
}
/**
* Parse a character-delimited String into an array of Strings.
*
* @param s character-delimited String to parse
* @param chDelim character delimiter
*
* @return an array of String objects parsed from the passed String
*/
public static String[] parseDelimitedString(String s, char chDelim)
{
return Formatting.parseDelimitedString(s, chDelim);
}
/**
* Format the content of the passed integer array as a delimited string.
*
* @param an the array
* @param sDelim the delimiter
*
* @return the formatted string
*/
public static String toDelimitedString(int[] an, String sDelim)
{
return Formatting.toDelimitedString(an, sDelim);
}
/**
* Format the content of the passed long array as a delimited string.
*
* @param al the array
* @param sDelim the delimiter
*
* @return the formatted string
*/
public static String toDelimitedString(long[] al, String sDelim)
{
return Formatting.toDelimitedString(al, sDelim);
}
/**
* Format the content of the passed Object array as a delimited string.
*
* @param ao the array
* @param sDelim the delimiter
*
* @return the formatted string
*/
public static String toDelimitedString(Object[] ao, String sDelim)
{
return Formatting.toDelimitedString(ao, sDelim);
}
/**
* Format the content of the passed Iterator as a delimited string.
*
* @param iter the Iterator
* @param sDelim the delimiter
*
* @return the formatted string
*/
public static String toDelimitedString(Iterator> iter, String sDelim)
{
return Formatting.toDelimitedString(iter, sDelim);
}
/**
* Capitalize a string.
*
* @param s the string to capitalize
*
* @return the capitalized string
*/
public static String capitalize(String s)
{
return Formatting.capitalize(s);
}
/**
* Truncate a string to the specified character count.
*
* @param s the String to be truncated
* @param cLimit expected character count
*
* @return the truncated String
*/
public static String truncateString(String s, int cLimit)
{
return Formatting.truncateString(s, cLimit);
}
/**
* Provide a string representation of elements within the collection until
* the concatenated string length exceeds {@code cLimit}.
*
* @param coll the collection of elements to describe
* @param cLimit expected character count
*
* @return the truncated string representation of the provided collection
*/
public static String truncateString(Collection> coll, int cLimit)
{
return Formatting.truncateString(coll, cLimit);
}
// ----- formatting support: bandwidth ----------------------------------
/**
* Parse the given string representation of a number of bytes per second.
* The supplied string must be in the format:
*
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[[B|b][P|p][S|s]]?
*
* where the first non-digit (from left to right) indicates the factor
* with which the preceding decimal value should be multiplied:
*
* - K or k (kilo, 210)
* - M or m (mega, 220)
* - G or g (giga, 230)
* - T or t (tera, 240)
*
*
* If the string value does not contain a factor, a factor of one is
* assumed.
*
* The optional last three characters indicate the unit of measure,
* [b][P|p][S|s] in the case of bits per second and
* [B][P|p][S|s] in the case of bytes per second. If the string
* value does not contain a unit, a unit of bits per second is assumed.
*
* @param s a string with the format:
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[[B|b][P|p][S|s]]?
*
* @return the number of bytes per second represented by the given string
*/
public static long parseBandwidth(String s)
{
return Formatting.parseBandwidth(s);
}
/**
* Parse the given string representation of a number of bytes per second.
* The supplied string must be in the format:
*
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[[B|b][P|p][S|s]]?
*
* where the first non-digit (from left to right) indicates the factor
* with which the preceding decimal value should be multiplied:
*
* - K or k (kilo, 210)
* - M or m (mega, 220)
* - G or g (giga, 230)
* - T or t (tera, 240)
*
*
* If the string value does not contain an explicit or implicit factor, a
* factor calculated by raising 2 to the given default power is used. The
* default power can be one of:
*
* - {@link #POWER_0}
* - {@link #POWER_K}
* - {@link #POWER_M}
* - {@link #POWER_G}
* - {@link #POWER_T}
*
*
* The optional last three characters indicate the unit of measure,
* [b][P|p][S|s] in the case of bits per second and
* [B][P|p][S|s] in the case of bytes per second. If the string
* value does not contain a unit, a unit of bits per second is assumed.
*
* @param s a string with the format:
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[[B|b][P|p][S|s]]?
* @param nDefaultPower the exponent used to calculate the factor used in
* the conversion if one is not implied by the given
* string
*
* @return the number of bytes per second represented by the given string
*/
public static long parseBandwidth(String s, int nDefaultPower)
{
return Formatting.parseBandwidth(s, nDefaultPower);
}
/**
* Format the passed bandwidth (in bytes per second) as a String that can
* be parsed by {@link #parseBandwidth} such that
* cb==parseBandwidth(toBandwidthString(cb)) holds true for
* all legal values of cbps.
*
* @param cbps the number of bytes per second
*
* @return a String representation of the given bandwidth
*/
public static String toBandwidthString(long cbps)
{
return Formatting.toBandwidthString(cbps);
}
/**
* Format the passed bandwidth (in bytes per second) as a String. This
* method will possibly round the memory size for purposes of producing a
* more-easily read String value unless the fExact parameters is
* passed as true; if fExact is true, then
* cb==parseBandwidth(toBandwidthString(cb, true)) holds true
* for all legal values of cbps.
*
* @param cbps the number of bytes per second
* @param fExact true if the String representation must be exact, or
* false if it can be an approximation
*
* @return a String representation of the given bandwidth
*/
public static String toBandwidthString(long cbps, boolean fExact)
{
return Formatting.toBandwidthString(cbps, fExact);
}
// ----- formatting support: memory size --------------------------------
/**
* Parse the given string representation of a number of bytes. The
* supplied string must be in the format:
*
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[B|b]?
*
* where the first non-digit (from left to right) indicates the factor
* with which the preceding decimal value should be multiplied:
*
* - K or k (kilo, 210)
* - M or m (mega, 220)
* - G or g (giga, 230)
* - T or t (tera, 240)
*
*
* If the string value does not contain a factor, a factor of one is
* assumed.
*
* The optional last character B or b indicates a unit
* of bytes.
*
* @param s a string with the format
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[B|b]?
*
* @return the number of bytes represented by the given string
*/
public static long parseMemorySize(String s)
{
return Formatting.parseMemorySize(s);
}
/**
* Parse the given string representation of a number of bytes. The
* supplied string must be in the format:
*
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[B|b]?
*
* where the first non-digit (from left to right) indicates the factor
* with which the preceding decimal value should be multiplied:
*
* - K or k (kilo, 210)
* - M or m (mega, 220)
* - G or g (giga, 230)
* - T or t (tera, 240)
*
*
* If the string value does not contain an explicit or implicit factor, a
* factor calculated by raising 2 to the given default power is used. The
* default power can be one of:
*
* - {@link #POWER_0}
* - {@link #POWER_K}
* - {@link #POWER_M}
* - {@link #POWER_G}
* - {@link #POWER_T}
*
*
* The optional last character B or b indicates a unit
* of bytes.
*
* @param s a string with the format
* [\d]+[[.][\d]+]?[K|k|M|m|G|g|T|t]?[B|b]?
* @param nDefaultPower the exponent used to calculate the factor used in
* the conversion if one is not implied by the given
* string
*
* @return the number of bytes represented by the given string
*/
public static long parseMemorySize(String s, int nDefaultPower)
{
return Formatting.parseMemorySize(s, nDefaultPower);
}
/**
* Format the passed memory size (in bytes) as a String that can be
* parsed by {@link #parseMemorySize} such that
* cb==parseMemorySize(toMemorySizeString(cb)) holds true for
* all legal values of cb.
*
* @param cb the number of bytes of memory
*
* @return a String representation of the given memory size
*/
public static String toMemorySizeString(long cb)
{
return Formatting.toMemorySizeString(cb);
}
/**
* Format the passed memory size (in bytes) as a String. This method will
* possibly round the memory size for purposes of producing a more-easily
* read String value unless the fExact parameters is passed as
* true; if fExact is true, then
* cb==parseMemorySize(toMemorySizeString(cb, true)) holds true
* for all legal values of cb.
*
* @param cb the number of bytes of memory
* @param fExact true if the String representation must be exact, or
* false if it can be an approximation
*
* @return a String representation of the given memory size
*/
public static String toMemorySizeString(long cb, boolean fExact)
{
return Formatting.toMemorySizeString(cb, fExact);
}
// ----- formatting support: time ---------------------------------------
/**
* Parse the given string representation of a time duration and return its
* value as a number of milliseconds. The supplied string must be in the
* format:
*
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
*
* where the first non-digits (from left to right) indicate the unit of
* time duration:
*
* - NS or ns (nanoseconds)
* - US or us (microseconds)
* - MS or ms (milliseconds)
* - S or s (seconds)
* - M or m (minutes)
* - H or h (hours)
* - D or d (days)
*
*
* If the string value does not contain a unit, a unit of milliseconds is
* assumed.
*
* @param s a string with the format
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
*
* @return the number of milliseconds represented by the given string
* rounded down to the nearest millisecond
*
* @see #parseTimeNanos(String)
*/
public static long parseTime(String s)
{
return Formatting.parseTime(s);
}
/**
* Parse the given string representation of a time duration and return its
* value as a number of milliseconds. The supplied string must be in the
* format:
*
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
*
* where the first non-digits (from left to right) indicate the unit of
* time duration:
*
* - NS or ns (nanoseconds)
* - US or us (microseconds)
* - MS or ms (milliseconds)
* - S or s (seconds)
* - M or m (minutes)
* - H or h (hours)
* - D or d (days)
*
*
* If the string value does not contain a unit, the specified default unit
* is assumed. The default unit can be one of:
*
* - {@link #UNIT_NS}
* - {@link #UNIT_US}
* - {@link #UNIT_MS}
* - {@link #UNIT_S}
* - {@link #UNIT_M}
* - {@link #UNIT_H}
* - {@link #UNIT_D}
*
*
* @param s a string with the format
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
* @param nDefaultUnit the unit to use in the conversion to milliseconds
* if one is not specified in the supplied string
*
* @return the number of milliseconds represented by the given string
* rounded down to the nearest millisecond
*
* @see #parseTimeNanos(String, int)
*/
public static long parseTime(String s, int nDefaultUnit)
{
return Formatting.parseTime(s, nDefaultUnit);
}
/**
* Parse the given string representation of a time duration and return its
* value as a number of nanoseconds. The supplied string must be in the
* format:
*
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
*
* where the first non-digits (from left to right) indicate the unit of
* time duration:
*
* - NS or ns (nanoseconds)
* - US or us (microseconds)
* - MS or ms (milliseconds)
* - S or s (seconds)
* - M or m (minutes)
* - H or h (hours)
* - D or d (days)
*
*
* If the string value does not contain a unit, a unit of nanoseconds is
* assumed.
*
* @param s a string with the format
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
*
* @return the number of nanoseconds represented by the given string
* rounded down to the nearest nanosecond
*/
public static long parseTimeNanos(String s)
{
return Formatting.parseTimeNanos(s);
}
/**
* Parse the given string representation of a time duration and return its
* value as a number of nanoseconds. The supplied string must be in the
* format:
*
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
*
* where the first non-digits (from left to right) indicate the unit of
* time duration:
*
* - NS or ns (nanoseconds)
* - US or us (microseconds)
* - MS or ms (milliseconds)
* - S or s (seconds)
* - M or m (minutes)
* - H or h (hours)
* - D or d (days)
*
*
* If the string value does not contain a unit, the specified default unit
* is assumed. The default unit can be one of:
*
* - {@link #UNIT_NS}
* - {@link #UNIT_US}
* - {@link #UNIT_MS}
* - {@link #UNIT_S}
* - {@link #UNIT_M}
* - {@link #UNIT_H}
* - {@link #UNIT_D}
*
*
* @param s a string with the format
* [\d]+[[.][\d]+]?[NS|ns|US|us|MS|ms|S|s|M|m|H|h|D|d]?
* @param nDefaultUnit the unit to use in the conversion to nanoseconds
* if one is not specified in the supplied string
*
* @return the number of nanoseconds represented by the given string
* rounded down to the nearest nanosecond
*/
public static long parseTimeNanos(String s, int nDefaultUnit)
{
return Formatting.parseTimeNanos(s, nDefaultUnit);
}
/**
* Format a long value into a human readable date/time string.
*
* @param ldt a Java long containing a date/time value
*
* @return a human readable date/time string
*/
public static String formatDateTime(long ldt)
{
return Formatting.formatDateTime(ldt);
}
// ----- formatting support: percentage ---------------------------------
/**
* Parse the given string representation of a percentage value and return
* its value as a float in the inclusive range of 0.0 and 1.0. The supplied
* string must be in the format:
*
* [\d]+[[.][\d]+]?[%]
*
* where the digits are within the closed interval [0.0, 100.0].
*
* @param s a string with the format [\d]+[[.][\d]+]?[%]
*
* @return a float representing the percentage value in the closed interval
* [0.0, 1.0]
*/
public static float parsePercentage(String s)
{
return Formatting.parsePercentage(s);
}
// ----- hashing --------------------------------------------------------
/**
* Return the hash code for the supplied object or 0 for null.
*
* @param o the object to hash
*
* @return the hash code for the supplied object
*/
public static int hashCode(Object o)
{
return HashHelper.hashCode(o);
}
// ----- comparisons ----------------------------------------------------
/**
* Compare two references for equality.
*
* @param o1 an object
* @param o2 an object to be compared with o1 for references equality
*
* @return true if equal, false otherwise
*/
public static boolean equals(Object o1, Object o2)
{
return Objects.equals(o1, o2);
}
/**
* Deeply compare two references for equality. This dives down into
* arrays, including nested arrays.
*
* @param o1 an object
* @param o2 an object to be compared with o1 for deeply equality
*
* @return true if deeply equal, false otherwise
*/
public static boolean equalsDeep(Object o1, Object o2)
{
return Objects.equalsDeep(o1, o2);
}
// ----- CRC32 ----------------------------------------------------------
/**
* Calculate a CRC32 value from a byte array.
*
* @param ab an array of bytes
*
* @return the 32-bit CRC value
*/
public static int toCrc(byte[] ab)
{
return Formatting.toCrc(ab);
}
/**
* Calculate a CRC32 value from a portion of a byte array.
*
* @param ab an array of bytes
* @param of the offset into the array
* @param cb the number of bytes to evaluate
*
* @return the 32-bit CRC value
*/
public static int toCrc(byte[] ab, int of, int cb)
{
return Formatting.toCrc(ab, of, cb, 0);
}
/**
* Continue to calculate a CRC32 value from a portion of a byte array.
*
* @param ab an array of bytes
* @param of the offset into the array
* @param cb the number of bytes to evaluate
* @param nCrc the previous CRC value
*
* @return the 32-bit CRC value
*/
public static int toCrc(byte[] ab, int of, int cb, int nCrc)
{
return Formatting.toCrc(ab, of, cb, nCrc);
}
/**
* Calculate a CRC32 value from a ByteSequence.
*
* @param seq a ByteSequence
*
* @return the 32-bit CRC value
*/
public static int toCrc(ByteSequence seq)
{
return Formatting.toCrc(seq);
}
/**
* Continue to calculate a CRC32 value from a portion of a ByteSequence .
*
* @param seq a ByteSequence
* @param of the offset into the ByteSequence
* @param cb the number of bytes to evaluate
* @param nCrc the previous CRC value
*
* @return the 32-bit CRC value
*/
public static int toCrc(ByteSequence seq, int of, int cb, int nCrc)
{
return Formatting.toCrc(seq, of, cb, nCrc);
}
// ----- time routines --------------------------------------------------
/**
* Return the number of milliseconds which have elapsed since the JVM was
* started.
*
* @return the number of milliseconds which have elapsed since the JVM was
* started
*/
public static long getUpTimeMillis()
{
return TimeHelper.getUpTimeMillis();
}
/**
* Returns a "safe" current time in milliseconds.
*
* @return the difference, measured in milliseconds, between
* the corrected current time and midnight, January 1, 1970 UTC.
*
* @see SafeClock
*/
public static long getSafeTimeMillis()
{
return TimeHelper.getSafeTimeMillis();
}
/**
* Returns the last "safe" time as computed by a previous call to
* the {@link #getSafeTimeMillis} method.
*
* @return the last "safe" time in milliseconds
*
* @see SafeClock
*/
public static long getLastSafeTimeMillis()
{
return TimeHelper.getLastSafeTimeMillis();
}
/**
* compute the number of milliseconds until the specified time.
*
* Note: this method will only return zero if ldtTimeout == Long.MAX_VALUE.
*
* @param ldtTimeout the timeout as computed by {@link #getSafeTimeMillis}
*
* @return the number of milliseconds to wait, or negative if the timeout
* has expired
*/
public static long computeSafeWaitTime(long ldtTimeout)
{
return TimeHelper.computeSafeWaitTime(ldtTimeout);
}
/**
* Gets the {@link TimeZone} for the given ID.
*
* This method will cache returned TimeZones to avoid the contention
* caused by the {@link TimeZone#getTimeZone(String)} implementation.
*
* @param sId the ID for a {@link TimeZone}
*
* @return the specified {@link TimeZone}, or the GMT zone if the
* given ID cannot be understood.
*
* @see TimeZone#getTimeZone(String)
*
* @since Coherence 12.1.3
*/
public static TimeZone getTimeZone(String sId)
{
return TimeHelper.getTimeZone(sId);
}
// ----- immutable intrinsic object caches ------------------------------
/**
* Factory method to produce Integer objects with an optimization that
* uses cached Integer objects for all relatively-low numbers.
*
* @param n an int
*
* @return an Integer whose value is the passed int
*
* @since Coherence 3.2
* @deprecated use {@link Integer#valueOf(int)}
*/
@Deprecated
public static Integer makeInteger(int n)
{
return n;
}
/**
* Factory method to produce Long objects with an optimization that
* uses cached Long objects for all relatively-low numbers.
*
* @param n a long
*
* @return a Long whose value is the passed long
*
* @since Coherence 3.2
* @deprecated use {@link Long#valueOf(long)}
*/
@Deprecated
public static Long makeLong(long n)
{
return n;
}
// ----- random routines ------------------------------------------------
/**
* Return a random number assigned to this process.
*
* This value will remain the same across invocations, but is generally different across JVMs.
*
* @return the process's random number.
*/
public static int getProcessRandom()
{
return Randoms.getProcessRandom();
}
/**
* Obtain a Random object that can be used to get random values.
*
* @return a random number generator
*
* @since Coherence 3.2
*/
public static Random getRandom()
{
return Randoms.getRandom();
}
/**
* Randomize the order of the elements within the passed collection.
*
* @param coll the Collection to randomize; the passed Collection is not
* altered
*
* @return a new and immutable List whose contents are identical to those
* of the passed collection except for the order in which they appear
*
* @since Coherence 3.2
*/
@SuppressWarnings("rawtypes")
public static List randomize(Collection coll)
{
return Randoms.randomize(coll);
}
/**
* Randomize the order of the elements within the passed array.
*
* @param a an array of objects to randomize
*
* @return the array that was passed in, and with its contents unchanged
* except for the order in which they appear
*
* @since Coherence 3.2
*/
public static Object[] randomize(Object[] a)
{
return Randoms.randomize(a);
}
/**
* Randomize the order of the elements within the passed array.
*
* @param a an array of int values to randomize
*
* @return the array that was passed in, and with its contents unchanged
* except for the order in which they appear
*
* @since Coherence 3.2
*/
public static int[] randomize(int[] a)
{
return Randoms.randomize(a);
}
/**
* Randomize the order of the elements within the passed array.
*
* @param a an array of long values to randomize
*
* @return the array that was passed in, and with its contents unchanged
* except for the order in which they appear
*
* @since Coherence 12.2.1.4
*/
public static long[] randomize(long[] a)
{
return Randoms.randomize(a);
}
/**
* Generates a random-length Binary within the length bounds provided
* whose contents are random bytes.
*
* @param cbMin the minimum number of bytes in the resulting Binary
* @param cbMax the maximum number of bytes in the resulting Binary
*
* @return a randomly generated Binary object
*
* @since Coherence 3.2
*/
public static Binary getRandomBinary(int cbMin, int cbMax)
{
return Randoms.getRandomBinary(cbMin, cbMax);
}
/**
* Generates a random-length Binary including {@code abHead} at the head of
* the Binary, in addition to random bytes within the length bounds provided.
*
* @param cbMin the minimum number of bytes in the resulting Binary
* @param cbMax the maximum number of bytes in the resulting Binary
* @param abHead the head of the returned Binary
*
* @return a randomly generated Binary object with a length of {@code
* [len(abHead) + cbMin, cbMax]}
*
* @since Coherence 12.1.3
*/
public static Binary getRandomBinary(int cbMin, int cbMax, byte...abHead)
{
return Randoms.getRandomBinary(cbMin, cbMax, abHead);
}
/**
* Generates a random-length String within the length bounds provided.
* If the ASCII option is indicated, the characters will be in the range
* [32-127], otherwise the characters will be in the range
* [0x0000-0xFFFF].
*
* @param cchMin the minimum length of the resulting String
* @param cchMax the maximum length of the resulting String
* @param fAscii true if the resulting String should contain only ASCII
* values
*
* @return a randomly generated String object
*
* @since Coherence 3.2
*/
public static String getRandomString(int cchMin, int cchMax, boolean fAscii)
{
return Randoms.getRandomString(cchMin, cchMax, fAscii);
}
// ----- validation methods ---------------------------------------------
/**
* Check the range of a value.
*
* @param lValue the value to check
* @param lFrom the lower limit of the range (inclusive)
* @param lTo the upper limit of the range (inclusive)
* @param sName the display name of the value
*
* @throws IllegalArgumentException if the value is out of range
*/
public static void checkRange(long lValue, long lFrom, long lTo, String sName)
{
if (lValue < lFrom || lValue > lTo)
{
throw new IllegalArgumentException(
sName + " value out of range [" + lFrom + ", " + lTo + "]: " + lValue);
}
}
/**
* Check that the specified object is non-null and return it.
*
* @param o the object to check
* @param sName the name of the corresponding parameter
* @param the type parameter for the object to check
*
* @return the specified object
*
* @throws IllegalArgumentException if o is null
*/
public static T checkNotNull(T o, String sName)
{
if (o == null)
{
throw new IllegalArgumentException(sName + " cannot be null");
}
return o;
}
/**
* Check that the specified string is neither a null nor an empty string.
*
* @param s the string to check
* @param sName the name of the corresponding parameter
*
* @throws IllegalArgumentException if s is null or empty string
*/
public static void checkNotEmpty(String s, String sName)
{
checkNotNull(s, sName);
if (s.length() == 0)
{
throw new IllegalArgumentException(sName + " cannot be empty");
}
}
// ---- miscellaneous ---------------------------------------------------
/**
* Calculate a modulo of two integer numbers. For a positive dividend the
* result is the same as the Java remainder operation (n % m
).
* For a negative dividend the result is still positive and equals to
* (n % m + m
).
*
* @param n the dividend
* @param m the divisor (must be positive)
*
* @return the modulo
*/
public static int mod(int n, int m)
{
return Hasher.mod(n, m);
}
/**
* Calculate a modulo of two long numbers. For a positive dividend the
* result is the same as the Java remainder operation (n % m
).
* For a negative dividend the result is still positive and equals to
* (n % m + m
).
*
* @param n the dividend
* @param m the divisor (must be positive)
*
* @return the modulo
*/
public static long mod(long n, long m)
{
return Hasher.mod(n, m);
}
// ----- properties -----------------------------------------------------
/**
* Obtains the current writer used for printing.
*
* @return the current writer used for printing; never null
*/
public static PrintWriter getOut()
{
return s_out;
}
/**
* Sets the current writer used for printing.
*
* @param writer the java.io.PrintWriter instance to use for printing;
* may be null
*/
public static void setOut(PrintWriter writer)
{
s_out = writer == null
? new PrintWriter(NullImplementation.getWriter(), true)
: writer;
}
/**
* Obtains the current writer used for tracing.
*
* @return the current writer used for tracing; never null
*/
public static PrintWriter getErr()
{
return s_err;
}
/**
* Sets the current writer used for tracing.
*
* @param writer the java.io.PrintWriter instance to use for tracing; may
* be null
*/
public static void setErr(PrintWriter writer)
{
s_err = writer == null
? new PrintWriter(NullImplementation.getWriter(), true)
: writer;
}
/**
* Obtains the current writer used for logging.
*
* @return the current writer used for logging; never null
*/
public static PrintWriter getLog()
{
return s_log;
}
/**
* Sets the current writer used for logging.
*
* @param writer the java.io.PrintWriter instance to use for logging; may
* be null
*/
public static void setLog(PrintWriter writer)
{
s_log = writer == null
? new PrintWriter(NullImplementation.getWriter(), true)
: writer;
}
/**
* Determine if the log is echoed to the console.
*
* @return true if the log is echoed to the console
*/
public static boolean isLogEcho()
{
return s_fEchoLog;
}
/**
* Specify whether the log should echo to the console.
*
* @param fEcho true if the log should echo to the console
*/
public static void setLogEcho(boolean fEcho)
{
s_fEchoLog = fEcho;
}
// ----- IO support -----------------------------------------------------
/**
* Read the contents out of the passed stream into the passed byte array
* and return the length read. This method will read up to the number of
* bytes that can fit into the passed array.
*
* @param stream a java.io.InputStream object to read from
* @param ab a byte array to read into
*
* @return the number of bytes read from the InputStream and stored into
* the passed byte array
*
* @throws IOException if an I/O error occurs
*/
public static int read(InputStream stream, byte[] ab)
throws IOException
{
return Reads.read(stream, ab);
}
/**
* Read the contents out of the passed stream and return the result as a
* byte array.
*
* @param stream a java.io.InputStream object to read from
*
* @return a byte array containing the contents of the passed InputStream
*
* @throws IOException if an I/O error occurs
*/
public static byte[] read(InputStream stream)
throws IOException
{
return Reads.read(stream);
}
/**
* Read the contents out of the passed stream and return the result as a
* byte array.
*
* @param stream a java.io.DataInput object to read from
*
* @return a byte array containing the contents of the passed stream
*
* @throws IOException if an I/O error occurs
*/
public static byte[] read(DataInput stream)
throws IOException
{
return Reads.read(stream);
}
/**
* Read the contents out of the passed stream and return the result as a
* byte array.
*
* @param stream a java.io.DataInputStream object to read from
*
* @return a byte array containing the contents of the passed InputStream
*
* @throws IOException if an I/O error occurs
*/
public static byte[] read(DataInputStream stream)
throws IOException
{
return Reads.read(stream);
}
/**
* Read the contents out of the passed Reader and return the result as a
* String.
*
* @param reader a java.io.Reader object to read from
*
* @return a String containing the contents of the passed Reader
*
* @throws IOException if an I/O error occurs
*/
public static String read(Reader reader)
throws IOException
{
return Reads.read(reader);
}
/**
* Read the contents out of the specified file and return the result as a
* byte array.
*
* @param file the java.io.File object to read the contents of
*
* @return the contents of the specified File as a byte array
*
* @throws IOException if an I/O error occurs
*/
public static byte[] read(File file)
throws IOException
{
return Reads.read(file);
}
/**
* Read the contents of the specified URL and return the result as a
* byte array.
*
* @param url the java.net.URL object to read the contents of
*
* @return the contents of the specified URL as a byte array
*
* @throws IOException if an I/O error occurs
*/
public static byte[] read(URL url)
throws IOException
{
return Reads.read(url);
}
// ----- merge primitive array support ---------------------------------
/**
* Merge two byte arrays.
*
* @param ab1 first array to merge
* @param ab2 second array to merge
*
* @return merged array
*/
public static byte[] mergeByteArray(byte[] ab1, byte[] ab2)
{
if (ab1 == null || ab1.length == 0)
{
return ab2;
}
if (ab2 == null || ab2.length == 0)
{
return ab1;
}
int nLen1 = ab1.length;
int nLen2 = ab2.length;
byte[] aMerged = Arrays.copyOf(ab1, nLen1 + nLen2);
System.arraycopy(ab2, 0, aMerged, nLen1, nLen2);
return aMerged;
}
/**
* Merge two boolean arrays.
*
* @param af1 first array to merge
* @param af2 second array to merge
*
* @return the merged array
*/
public static boolean[] mergeBooleanArray(boolean[] af1, boolean[] af2)
{
if (af1 == null || af1.length == 0)
{
return af2;
}
if (af2 == null || af2.length == 0)
{
return af1;
}
int nLen1 = af1.length;
int nLen2 = af2.length;
boolean[] aMerged = Arrays.copyOf(af1, nLen1 + nLen2);
System.arraycopy(af2, 0, aMerged, nLen1, nLen2);
return aMerged;
}
/**
* Merge two double arrays.
*
* @param adfl1 first array to merge
* @param adfl2 second array to merge
*
* @return the merged array
*/
public static double[] mergeDoubleArray(double[] adfl1, double[] adfl2)
{
if (adfl1 == null || adfl1.length == 0)
{
return adfl2;
}
if (adfl2 == null || adfl2.length == 0)
{
return adfl1;
}
int nLen1 = adfl1.length;
int nLen2 = adfl2.length;
double[] aMerged = Arrays.copyOf(adfl1, nLen1 + nLen2);
System.arraycopy(adfl2, 0, aMerged, nLen1, nLen2);
return aMerged;
}
/**
* Merge two float arrays.
*
* @param afl1 first array to merge
* @param afl2 second array to merge
*
* @return merged array
*/
public static float[] mergeFloatArray(float[] afl1, float[] afl2)
{
if (afl1 == null || afl1.length == 0)
{
return afl2;
}
if (afl2 == null || afl2.length == 0)
{
return afl1;
}
int nLen1 = afl1.length;
int nLen2 = afl2.length;
float[] aMerged = Arrays.copyOf(afl1, nLen1 + nLen2);
System.arraycopy(afl2, 0, aMerged, nLen1, nLen2);
return aMerged;
}
/**
* Merge two long arrays.
*
* @param al1 first array to merge
* @param al2 second array to merge
*
* @return merged array
*/
public static long[] mergeLongArray(long[] al1, long[] al2)
{
if (al1 == null || al1.length == 0)
{
return al2;
}
if (al2 == null || al2.length == 0)
{
return al1;
}
int nLen1 = al1.length;
int nLen2 = al2.length;
long[] aMerged = Arrays.copyOf(al1, nLen1 + nLen2);
System.arraycopy(al2, 0, aMerged, nLen1, nLen2);
return aMerged;
}
/**
* Merge two int arrays.
*
* @param ai1 first array to merge
* @param ai2 second array to merge
*
* @return merged array
*/
public static int[] mergeIntArray(int[] ai1, int[] ai2)
{
if (ai1 == null || ai1.length == 0)
{
return ai2;
}
if (ai2 == null || ai2.length == 0)
{
return ai1;
}
int nLen1 = ai1.length;
int nLen2 = ai2.length;
int[] aMerged = Arrays.copyOf(ai1, nLen1 + nLen2);
System.arraycopy(ai2, 0, aMerged, nLen1, nLen2);
return aMerged;
}
/**
* Merge two char arrays.
*
* @param ac1 first array to merge
* @param ac2 second array to merge
*
* @return merged array
*/
public static char[] mergeCharArray(char[] ac1, char[] ac2)
{
if (ac1 == null || ac1.length == 0)
{
return ac2;
}
if (ac2 == null || ac2.length == 0)
{
return ac1;
}
int nLen1 = ac1.length;
int nLen2 = ac2.length;
char[] aMerged = Arrays.copyOf(ac1, nLen1 + nLen2);
System.arraycopy(ac2, 0, aMerged, nLen1, nLen2);
return aMerged;
}
/**
* Merge two array with type T elements.
*
* @param a1 first array to merge
* @param a2 second array to merge
*
* @param type of array element
*
* @return the merged array
*/
public static T[] mergeArray(T[] a1, T[] a2)
{
if (a1 == null || a1.length == 0)
{
return a2;
}
if (a2 == null || a2.length == 0)
{
return a1;
}
int nLen1 = a1.length;
int nLen2 = a2.length;
T[] aMerged = (T[]) Arrays.copyOf(a1, nLen1 + nLen2);
System.arraycopy(a2, 0, aMerged, nLen1, nLen2);
return (T[]) aMerged;
}
// ----- inner class: LoggingWriter -----------------------------------
/**
* Inner class for over-riding the destination of log(), out() and err()
* calls.
*/
public static class LoggingWriter
extends PrintWriter
{
/**
* Construct a PrintWriter that logs using the {@link CacheFactory#log}
* method.
*
* @param nSev the severity to log messages with
*/
public LoggingWriter(int nSev)
{
super(new CharArrayWriter());
m_nSev = nSev;
}
/**
* Log the accumulated String using the logging severity that this
* PrintWriter was configured with.
*/
@Override
public void println()
{
CharArrayWriter out = (CharArrayWriter) this.out;
//noinspection SynchronizeOnNonFinalField
synchronized (lock)
{
String s = out.toString();
out.reset();
Logger.log(s, m_nSev);
}
}
/**
* The severity that this PrintWriter logs with.
*/
private final int m_nSev;
}
// ----- constants ------------------------------------------------------
/**
* Integer constant representing a unit of nanoseconds.
*
* @see #parseTimeNanos(String, int)
*/
public static final int UNIT_NS = -1000000;
/**
* Integer constant representing a unit of microseconds.
*
* @see #parseTimeNanos(String, int)
*/
public static final int UNIT_US = -1000;
/**
* Integer constant representing a unit of milliseconds.
*
* @see #parseTime(String, int)
*/
public static final int UNIT_MS = 1;
/**
* Integer constant representing a unit of seconds.
*
* @see #parseTime(String, int)
*/
public static final int UNIT_S = 1000*UNIT_MS;
/**
* Integer constant representing a unit of minutes.
*
* @see #parseTime(String, int)
*/
public static final int UNIT_M = 60*UNIT_S;
/**
* Integer constant representing a unit of hours.
*
* @see #parseTime(String, int)
*/
public static final int UNIT_H = 60*UNIT_M;
/**
* Integer constant representing a unit of days.
*
* @see #parseTime(String, int)
*/
public static final int UNIT_D = 24*UNIT_H;
/**
* Integer constant representing an exponent of zero.
*
* @see #parseBandwidth(String, int)
* @see #parseMemorySize(String, int)
*/
public static final int POWER_0 = 0;
/**
* Integer constant representing an exponent of 10.
*
* @see #parseBandwidth(String, int)
* @see #parseMemorySize(String, int)
*/
public static final int POWER_K = 10;
/**
* Integer constant representing an exponent of 20.
*
* @see #parseBandwidth(String, int)
* @see #parseMemorySize(String, int)
*/
public static final int POWER_M = 20;
/**
* Integer constant representing an exponent of 30.
*
* @see #parseBandwidth(String, int)
* @see #parseMemorySize(String, int)
*/
public static final int POWER_G = 30;
/**
* Integer constant representing an exponent of 40.
*
* @see #parseBandwidth(String, int)
* @see #parseMemorySize(String, int)
*/
public static final int POWER_T = 40;
/**
* The minimum logging level indicator.
*/
public static final int LOG_MIN = 0;
/**
* The maximum logging level indicator.
*/
public static final int LOG_MAX = 9;
/**
* It is expected that items with a log level of 0 will always be logged.
*/
public static final int LOG_ALWAYS = 0;
/**
* Log level 1 indicates an error.
*/
public static final int LOG_ERR = 1;
/**
* Log level 2 indicates a warning.
*/
public static final int LOG_WARN = 2;
/**
* Log level 3 indicates information that should likely be logged.
*/
public static final int LOG_INFO = 3;
/**
* Log level 4 indicates configuration related log message.
*/
public static final int LOG_CONFIG = 4;
/**
* As of Coherence 3.2, the default logging level is 5, so using the level
* of 5 will show up in the logs by default as a debug message.
*/
public static final int LOG_DEBUG = 5;
/**
* As of Coherence 3.2, the default logging level is 5, so using a level
* higher than 5 will be "quiet" by default, meaning that it will not show
* up in the logs unless the configured logging level is increased.
*/
public static final int LOG_QUIET = 6;
// ----- data members ---------------------------------------------------
/**
* The writer to use for print output.
*/
private static PrintWriter s_out = new PrintWriter(System.out, true);
/**
* The writer to use for trace output.
*/
private static PrintWriter s_err = new PrintWriter(System.err, true);
/**
* The writer to use for logging. By default, there is no persistent
* log.
*/
private static PrintWriter s_log = new PrintWriter(NullImplementation.getWriter(), true);
/**
* Option to log to the console in addition to the logging writer. By
* default, all logged messages are echoed to the console.
*/
private static boolean s_fEchoLog = true;
/**
* The configured ThreadFactory.
*/
private static final ThreadFactory s_threadFactory = instantiateThreadFactory();
// initialize logging through Coherence
static
{
setOut(new LoggingWriter(LOG_ALWAYS));
setErr(new LoggingWriter(LOG_ERR));
setLog(new LoggingWriter(LOG_INFO));
setLogEcho(false);
}
}