/*
* Copyright (C) 2013 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zaxxer.hikari.util;
import static java.lang.Thread.currentThread;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Locale;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
Author: Brett Wooldridge
/**
*
* @author Brett Wooldridge
*/
public final class UtilityElf
{
A constant for SQL Server's Snapshot isolation level
/**
* A constant for SQL Server's Snapshot isolation level
*/
private static final int SQL_SERVER_SNAPSHOT_ISOLATION_LEVEL = 4096;
Returns: null if string is null or empty
/**
*
* @return null if string is null or empty
*/
public static String getNullIfEmpty(final String text)
{
return text == null ? null : text.trim().isEmpty() ? null : text.trim();
}
Sleep and suppress InterruptedException (but re-signal it).
Params: - millis – the number of milliseconds to sleep
/**
* Sleep and suppress InterruptedException (but re-signal it).
*
* @param millis the number of milliseconds to sleep
*/
public static void quietlySleep(final long millis)
{
try {
Thread.sleep(millis);
}
catch (InterruptedException e) {
// I said be quiet!
currentThread().interrupt();
}
}
Checks whether an object is an instance of given type without throwing exception when the class is not loaded.
Params: - obj – the object to check
- className – String class
Returns: true if object is assignable from the type, false otherwise or when the class cannot be loaded
/**
* Checks whether an object is an instance of given type without throwing exception when the class is not loaded.
* @param obj the object to check
* @param className String class
* @return true if object is assignable from the type, false otherwise or when the class cannot be loaded
*/
public static boolean safeIsAssignableFrom(Object obj, String className) {
try {
Class<?> clazz = Class.forName(className);
return clazz.isAssignableFrom(obj.getClass());
} catch (ClassNotFoundException ignored) {
return false;
}
}
Create and instance of the specified class using the constructor matching the specified
arguments.
Params: - className – the name of the class to instantiate
- clazz – a class to cast the result as
- args – arguments to a constructor
Type parameters: - <T> – the class type
Returns: an instance of the specified class
/**
* Create and instance of the specified class using the constructor matching the specified
* arguments.
*
* @param <T> the class type
* @param className the name of the class to instantiate
* @param clazz a class to cast the result as
* @param args arguments to a constructor
* @return an instance of the specified class
*/
public static <T> T createInstance(final String className, final Class<T> clazz, final Object... args)
{
if (className == null) {
return null;
}
try {
Class<?> loaded = UtilityElf.class.getClassLoader().loadClass(className);
if (args.length == 0) {
return clazz.cast(loaded.newInstance());
}
Class<?>[] argClasses = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
argClasses[i] = args[i].getClass();
}
Constructor<?> constructor = loaded.getConstructor(argClasses);
return clazz.cast(constructor.newInstance(args));
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
Create a ThreadPoolExecutor.
Params: - queueSize – the queue size
- threadName – the thread name
- threadFactory – an optional ThreadFactory
- policy – the RejectedExecutionHandler policy
Returns: a ThreadPoolExecutor
/**
* Create a ThreadPoolExecutor.
*
* @param queueSize the queue size
* @param threadName the thread name
* @param threadFactory an optional ThreadFactory
* @param policy the RejectedExecutionHandler policy
* @return a ThreadPoolExecutor
*/
public static ThreadPoolExecutor createThreadPoolExecutor(final int queueSize, final String threadName, ThreadFactory threadFactory, final RejectedExecutionHandler policy)
{
if (threadFactory == null) {
threadFactory = new DefaultThreadFactory(threadName, true);
}
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(queueSize);
ThreadPoolExecutor executor = new ThreadPoolExecutor(1 /*core*/, 1 /*max*/, 5 /*keepalive*/, SECONDS, queue, threadFactory, policy);
executor.allowCoreThreadTimeOut(true);
return executor;
}
Create a ThreadPoolExecutor.
Params: - queue – the BlockingQueue to use
- threadName – the thread name
- threadFactory – an optional ThreadFactory
- policy – the RejectedExecutionHandler policy
Returns: a ThreadPoolExecutor
/**
* Create a ThreadPoolExecutor.
*
* @param queue the BlockingQueue to use
* @param threadName the thread name
* @param threadFactory an optional ThreadFactory
* @param policy the RejectedExecutionHandler policy
* @return a ThreadPoolExecutor
*/
public static ThreadPoolExecutor createThreadPoolExecutor(final BlockingQueue<Runnable> queue, final String threadName, ThreadFactory threadFactory, final RejectedExecutionHandler policy)
{
if (threadFactory == null) {
threadFactory = new DefaultThreadFactory(threadName, true);
}
ThreadPoolExecutor executor = new ThreadPoolExecutor(1 /*core*/, 1 /*max*/, 5 /*keepalive*/, SECONDS, queue, threadFactory, policy);
executor.allowCoreThreadTimeOut(true);
return executor;
}
// ***********************************************************************
// Misc. public methods
// ***********************************************************************
Get the int value of a transaction isolation level by name.
Params: - transactionIsolationName – the name of the transaction isolation level
Returns: the int value of the isolation level or -1
/**
* Get the int value of a transaction isolation level by name.
*
* @param transactionIsolationName the name of the transaction isolation level
* @return the int value of the isolation level or -1
*/
public static int getTransactionIsolation(final String transactionIsolationName)
{
if (transactionIsolationName != null) {
try {
// use the english locale to avoid the infamous turkish locale bug
final String upperName = transactionIsolationName.toUpperCase(Locale.ENGLISH);
if (upperName.startsWith("TRANSACTION_")) {
Field field = Connection.class.getField(upperName);
return field.getInt(null);
}
final int level = Integer.parseInt(transactionIsolationName);
switch (level) {
case Connection.TRANSACTION_READ_UNCOMMITTED:
case Connection.TRANSACTION_READ_COMMITTED:
case Connection.TRANSACTION_REPEATABLE_READ:
case Connection.TRANSACTION_SERIALIZABLE:
case Connection.TRANSACTION_NONE:
case SQL_SERVER_SNAPSHOT_ISOLATION_LEVEL: // a specific isolation level for SQL server only
return level;
default:
throw new IllegalArgumentException();
}
}
catch (Exception e) {
throw new IllegalArgumentException("Invalid transaction isolation value: " + transactionIsolationName);
}
}
return -1;
}
public static final class DefaultThreadFactory implements ThreadFactory {
private final String threadName;
private final boolean daemon;
public DefaultThreadFactory(String threadName, boolean daemon) {
this.threadName = threadName;
this.daemon = daemon;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, threadName);
thread.setDaemon(daemon);
return thread;
}
}
}