package org.openntf.domino.xsp.helpers; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import lotus.domino.NotesFactory; import lotus.domino.Session; import org.openntf.domino.utils.DominoUtils; import org.openntf.domino.utils.Factory; import com.ibm.domino.napi.c.xsp.XSPNative; import com.ibm.domino.xsp.module.nsf.NSFComponentModule; import com.ibm.domino.xsp.module.nsf.NotesContext; /** * Class for creating background tasks */ public abstract class BackgroundRunnable implements Runnable { public static class ThreadContext { private final String dbpath; private final NSFComponentModule module; private final String servername; private final String username; public ThreadContext(final String username, final String servername, final String dpath) { this.username = username; this.servername = servername; this.dbpath = dpath; NotesContext current = NotesContext.getCurrentUnchecked(); if (current == null) { this.module = null; // Ummmm... bad things are about to happen... } else { this.module = NotesContext.getCurrent().getModule(); } } public ThreadContext(final String username, final String servername, final String dpath, final NotesContext sourceCtx) { this.username = username; this.servername = servername; this.dbpath = dpath; this.module = sourceCtx.getModule(); } public lotus.domino.Database getContextDatabase(final lotus.domino.Session session) { try { session.getDatabase(this.servername, this.dbpath); } catch (Throwable t) { DominoUtils.handleException(t); } return null; } public lotus.domino.Session getNrpcSessionAsHost() { lotus.domino.Session result = null; try { result = AccessController.doPrivileged(new PrivilegedExceptionAction<lotus.domino.Session>() { @Override public Session run() throws Exception { return NotesFactory.createSessionWithFullAccess(); } }); } catch (PrivilegedActionException e) { DominoUtils.handleException(e); } return result; } public lotus.domino.Session getTrustedSession() { lotus.domino.Session result = null; try { result = AccessController.doPrivileged(new PrivilegedExceptionAction<lotus.domino.Session>() { @Override public Session run() throws Exception { return NotesFactory.createTrustedSession(); } }); } catch (PrivilegedActionException e) { DominoUtils.handleException(e); } return result; } public lotus.domino.Session getXspSessionAsUser() { final NSFComponentModule mod = this.module; lotus.domino.Session result = null; try { result = AccessController.doPrivileged(new PrivilegedExceptionAction<lotus.domino.Session>() { @Override public Session run() throws Exception { NotesContext nc = new NotesContext(mod); NotesContext.initThread(nc); long hList = com.ibm.domino.napi.c.NotesUtil.createUserNameList(username); return XSPNative.createXPageSession(username, hList, true, false); } }); } catch (PrivilegedActionException e) { DominoUtils.handleException(e); } return result; } public void initClassLoader(final Thread t) { if (this.module != null) { t.setContextClassLoader(this.module.getModuleClassLoader()); } } public boolean isXspContext() { return null != module; } } private static ThreadLocal<lotus.domino.Session> localSession_ = new ThreadLocal<lotus.domino.Session>() { }; private ThreadContext threadContext_; private boolean useOpenntf_ = true; public BackgroundRunnable(final ThreadContext threadContext) { setThreadContext(threadContext); } public BackgroundRunnable(final ThreadContext threadContext, final boolean useOpenntf) { setThreadContext(threadContext); useOpenntf_ = useOpenntf; } protected lotus.domino.Session getSession() { return BackgroundRunnable.localSession_.get(); } private ThreadContext getThreadContext() { return threadContext_; } private void initSession(final ThreadContext tc) { lotus.domino.Session delegate = null; if (tc.isXspContext()) { delegate = tc.getXspSessionAsUser(); } else { delegate = tc.getNrpcSessionAsHost(); } if (useOpenntf_) { BackgroundRunnable.localSession_.set(Factory.fromLotus(delegate, org.openntf.domino.Session.SCHEMA, null)); } else { BackgroundRunnable.localSession_.set(delegate); } } @Override public void run() { ThreadContext tc = getThreadContext(); tc.initClassLoader(Thread.currentThread()); try { initSession(tc); if (tc.isXspContext()) { runXsp(); } else { runNrpc(); } } catch (Throwable t) { DominoUtils.handleException(t); } finally { termSession(); } } protected abstract void runNrpc(); protected abstract void runXsp(); private void setThreadContext(final ThreadContext ctx) { threadContext_ = ctx; } private void termSession() { lotus.domino.Session s = BackgroundRunnable.localSession_.get(); if (null != s) { try { s.recycle(); } catch (Exception e) { DominoUtils.handleException(e); } BackgroundRunnable.localSession_.set(null); } } }