blob: 15dfedd693cd9265a6672238520a464b4db1f608 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.sling.commons.threads.impl;
import java.util.Locale;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.sling.commons.threads.ThreadPoolConfig;
/**
* This class is responsible to create new Thread instances.
* It's a very basic implementation.
*
*/
public final class ExtendedThreadFactory implements ThreadFactory {
/** Template for thread names, for use with String#format() */
private static final String THREAD_NAME_TEMPLATE = "sling-%s-%d";
/** The real factory. */
private final ThreadFactory factory;
/** The name of the thread pool */
private final String name;
/** The priority of newly created Threads */
private final int priority;
/** The daemon mode */
private final boolean isDaemon;
/** Thread counter for use in thread name */
private final AtomicInteger threadCounter;
/**
* Create a new wrapper for a thread factory handling the
*
* @param name The name of the thread pool.
* @param priority A non null value.
* @param isDaemon Whether new {@link Thread}s should run as daemons.
*/
public ExtendedThreadFactory(final ThreadFactory factory,
final String name,
final ThreadPoolConfig.ThreadPriority priority,
final boolean isDaemon) {
this.factory = factory;
this.name = normalizeName(name);
this.priority = convertPriority(priority);
this.isDaemon = isDaemon;
this.threadCounter = new AtomicInteger(1);
}
private String normalizeName(final String name) {
final String n = name.toLowerCase(Locale.ENGLISH).replaceAll("\\s+", "-");
return stripPrefixes(n, "apache-sling-", "sling-");
}
private int convertPriority(final ThreadPoolConfig.ThreadPriority priority) {
if (priority == null) {
throw new IllegalStateException("Prioriy must not be null.");
}
switch (priority) {
case MIN :
return Thread.MIN_PRIORITY;
case MAX :
return Thread.MAX_PRIORITY;
case NORM :
default: // this can never happen
return Thread.NORM_PRIORITY;
}
}
/**
* Invoke the thread factory and set the daemon flag and priority.
* @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
*/
public Thread newThread( final Runnable command ) {
final Thread thread = this.factory.newThread(command);
thread.setName(nextThreadName());
thread.setPriority( this.priority );
thread.setDaemon( this.isDaemon );
return thread;
}
private String nextThreadName() {
return String.format(THREAD_NAME_TEMPLATE, this.name, this.threadCounter.getAndIncrement());
}
private static String stripPrefixes(final String name, final String... prefixes) {
for (final String prefix : prefixes) {
if (name.startsWith(prefix)) {
return name.substring(prefix.length());
}
}
return name;
}
}