/*
* Copyright 2013
*
* 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 org.openntf.domino.thread;
import java.util.logging.Logger;
import lotus.domino.NotesThread;
import org.openntf.domino.session.ISessionFactory;
import org.openntf.domino.utils.DominoUtils;
import org.openntf.domino.utils.Factory;
import org.openntf.domino.utils.Factory.SessionType;
/**
* The Class DominoThread extends the NotesThread and clones the current SessionFactory.
*/
public class DominoThread extends NotesThread {
private static final Logger log_ = Logger.getLogger(DominoThread.class.getName());
private transient Runnable runnable_;
protected int nativeId_;
private final ISessionFactory sessionFactory_;
private Factory.ThreadConfig sourceThreadConfig = Factory.getThreadConfig();
/**
* The shutdown hook is executed if the thread is still running before the Factory is shut down.
*/
private Runnable shutdownHook = new Runnable() {
@Override
public void run() {
Factory.println(DominoThread.this, "Shutdown " + DominoThread.this);
DominoThread.this.interrupt();
try {
DominoThread.this.join(30 * 1000); // give the thread 30 seconds to join after interrupt.
} catch (InterruptedException e) {
}
if (DominoThread.this.isAlive()) {
Factory.println(DominoThread.this, "WARNING " + DominoThread.this + " is still alive after 30 secs. Continuing anyway.");
}
}
};
/**
* Instantiates a new domino thread.
*/
public DominoThread() {
sessionFactory_ = Factory.getSessionFactory(SessionType.CURRENT);
}
/**
* Instantiates a new domino thread.
*
* @param threadName
* the thread name
*/
public DominoThread(final String threadName) {
super(threadName);
sessionFactory_ = Factory.getSessionFactory(SessionType.CURRENT);
}
/**
* Instantiates a new domino thread.
*
* @param runnable
* the runnable
*/
public DominoThread(final Runnable runnable) {
super();
runnable_ = runnable;
sessionFactory_ = Factory.getSessionFactory(SessionType.CURRENT);
}
/**
* Instantiates a new domino thread.
*
* @param runnable
* the runnable
* @param threadName
* the thread name
*/
public DominoThread(final Runnable runnable, final String threadName) {
super(threadName);
runnable_ = runnable;
sessionFactory_ = Factory.getSessionFactory(SessionType.CURRENT);
}
/**
* Instantiates a new domino thread.
*
* @param runnable
* the runnable
* @param threadName
* the thread name
* @param sessionFactory
* the session factory
*/
public DominoThread(final Runnable runnable, final String threadName, final ISessionFactory sessionFactory) {
super(threadName);
runnable_ = runnable;
sessionFactory_ = sessionFactory;
}
/**
* Instantiates a new domino thread.
*
* @param threadName
* the thread name
* @param sessionFactory
* the session factory
*/
public DominoThread(final String threadName, final ISessionFactory sessionFactory) {
super(threadName);
sessionFactory_ = sessionFactory;
}
/**
* Instantiates a new domino thread.
*
* @param runnable
* the runnable
* @param threadName
* the thread name
* @param sessionFactory
* the session factory
*/
public DominoThread(final ISessionFactory sessionFactory) {
super();
sessionFactory_ = sessionFactory;
}
/**
* Instantiates a new domino thread.
*
* @param runnable
* the runnable
* @param threadName
* the thread name
* @param sessionFactory
* the session factory
*/
public DominoThread(final Runnable runnable, final ISessionFactory sessionFactory) {
super();
runnable_ = runnable;
sessionFactory_ = sessionFactory;
}
public Runnable getRunnable() {
return runnable_;
}
/*
* (non-Javadoc)
*
* @see java.lang.Thread#run()
*/
@Override
public void runNotes() {
try {
getRunnable().run(); //NTF: we're already inside the NotesThread.run();
//Note: if the runnable is a ThreadPoolExecutor.Worker, then this process will not end
//until the Executor is shutdown or the keep alive expires.
} catch (Throwable t) {
t.printStackTrace();
DominoUtils.handleException(t);
}
}
@Override
public void initThread() {
super.initThread();
nativeId_ = this.getNativeThreadID();
log_.fine("DEBUG: Initializing a " + toString());
Factory.initThread(sourceThreadConfig);
Factory.setSessionFactory(sessionFactory_, SessionType.CURRENT);
Factory.addShutdownHook(shutdownHook);
}
@Override
public void termThread() {
log_.fine("DEBUG: Terminating a " + toString());
Factory.removeShutdownHook(shutdownHook);
super.termThread();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getName());
if (nativeId_ != 0) {
sb.append(String.format(" [%04x]", nativeId_));
}
sb.append(": ");
if (getRunnable() != null) {
sb.append(getRunnable().getClass().getName());
} else {
sb.append(getClass().getName());
}
return sb.toString();
}
}