X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=server%2Fruntime%2Forg.argeo.server.jcr%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fjcr%2FThreadBoundJcrSessionFactory.java;h=003bcc69b552fd956e5db28b8efd27e72f81237b;hb=2d4dd736ab07b1ef3aaec0a9e5d29f30c551de9c;hp=1a37e3e855f5edb0cc5fc43570ec7921d21fa584;hpb=2745f0c8c57d9468855179d56f858fb2448f779c;p=lgpl%2Fargeo-commons.git diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java index 1a37e3e85..003bcc69b 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java @@ -17,6 +17,7 @@ package org.argeo.jcr; import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; @@ -35,13 +36,9 @@ import javax.jcr.SimpleCredentials; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; /** Proxy JCR sessions and attach them to calling threads. */ -public class ThreadBoundJcrSessionFactory implements FactoryBean, - InitializingBean, DisposableBean { +public abstract class ThreadBoundJcrSessionFactory { private final static Log log = LogFactory .getLog(ThreadBoundJcrSessionFactory.class); @@ -73,8 +70,11 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, } /** Logs in to the repository using various strategies. */ - protected Session login() { - // discard sesison previoussly attached to this thread + protected synchronized Session login() { + if (!isActive()) + throw new ArgeoException("Thread bound session factory inactive"); + + // discard session previously attached to this thread Thread thread = Thread.currentThread(); if (activeSessions.containsKey(thread.getId())) { Session oldSession = activeSessions.remove(thread.getId()); @@ -123,12 +123,15 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, return proxiedSession; } - public void afterPropertiesSet() throws Exception { + public void init() throws Exception { monitoringThread = new MonitoringThread(); monitoringThread.start(); } - public synchronized void destroy() throws Exception { + public synchronized void dispose() throws Exception { + if (activeSessions.size() == 0) + return; + if (log.isDebugEnabled()) log.debug("Cleaning up " + activeSessions.size() + " active JCR sessions..."); @@ -138,7 +141,6 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, sess.logout(); } activeSessions.clear(); - monitoringThread.join(1000); } protected Boolean isActive() { @@ -150,6 +152,39 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, notifyAll(); } + protected synchronized void removeSession(Thread thread) { + if (!isActive()) + return; + activeSessions.remove(thread.getId()); + threads.remove(thread); + } + + protected synchronized void cleanDeadThreads() { + if (!isActive()) + return; + Iterator it = threads.iterator(); + while (it.hasNext()) { + Thread thread = it.next(); + if (!thread.isAlive() && isActive()) { + if (activeSessions.containsKey(thread.getId())) { + Session session = activeSessions.get(thread.getId()); + activeSessions.remove(thread.getId()); + session.logout(); + if (log.isDebugEnabled()) + log.debug("Cleaned up JCR session (userID=" + + session.getUserID() + ") from dead thread " + + thread.getId()); + } + it.remove(); + } + } + try { + wait(1000); + } catch (InterruptedException e) { + // silent + } + } + public Class getObjectType() { return Session.class; } @@ -190,7 +225,7 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, protected class JcrSessionInvocationHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable { + throws Throwable, RepositoryException { Session threadSession = session.get(); if (threadSession == null) { if ("logout".equals(method.getName()))// no need to login @@ -200,20 +235,25 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, threadSession = login(); } - Object ret = method.invoke(threadSession, args); + preCall(threadSession); + Object ret; + try { + ret = method.invoke(threadSession, args); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof RepositoryException) + throw (RepositoryException) cause; + else + throw cause; + } if ("logout".equals(method.getName())) { - synchronized (ThreadBoundJcrSessionFactory.this) { - session.remove(); - Thread thread = Thread.currentThread(); - if (isActive()) { - activeSessions.remove(thread.getId()); - threads.remove(thread); - } - if (log.isTraceEnabled()) - log.trace("Logged out JCR session (userId=" - + threadSession.getUserID() + ") on thread " - + thread.getId()); - } + session.remove(); + Thread thread = Thread.currentThread(); + removeSession(thread); + if (log.isTraceEnabled()) + log.trace("Logged out JCR session (userId=" + + threadSession.getUserID() + ") on thread " + + thread.getId()); } return ret; } @@ -222,35 +262,14 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, /** Monitors registered thread in order to clean up dead ones. */ private class MonitoringThread extends Thread { + public MonitoringThread() { + super("ThreadBound JCR Session Monitor"); + } + @Override public void run() { while (isActive()) { - Iterator it = threads.iterator(); - while (it.hasNext()) { - Thread thread = it.next(); - if (!thread.isAlive() && isActive()) { - if (activeSessions.containsKey(thread.getId())) { - Session session = activeSessions - .get(thread.getId()); - activeSessions.remove(thread.getId()); - session.logout(); - if (log.isDebugEnabled()) - log.debug("Cleaned up JCR session (userID=" - + session.getUserID() - + ") from dead thread " - + thread.getId()); - } - it.remove(); - } - } - - synchronized (ThreadBoundJcrSessionFactory.this) { - try { - ThreadBoundJcrSessionFactory.this.wait(1000); - } catch (InterruptedException e) { - // silent - } - } + cleanDeadThreads(); } }