X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=server%2Fruntime%2Forg.argeo.server.jcr%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fjcr%2FThreadBoundJcrSessionFactory.java;h=4c8ee90105155bc21393a755cbb73744c38c398c;hb=7f357d2250d433d6b44328d419c1e62d9655c2df;hp=d05d8450a4608f94c5f6e54f228aec1e3d0e2b63;hpb=019e0f2af17286be08ab17c1c9e1d8ba871ec9b2;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 d05d8450a..4c8ee9010 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,17 +36,15 @@ 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); private Repository repository; + /** can be injected as list, only used if repository is null */ + private List repositories; private ThreadLocal session = new ThreadLocal(); private final Session proxiedSession; @@ -73,7 +72,7 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, } /** Logs in to the repository using various strategies. */ - protected Session login() { + protected synchronized Session login() { if (!isActive()) throw new ArgeoException("Thread bound session factory inactive"); @@ -91,7 +90,7 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, // Security) if (!forceDefaultCredentials) try { - newSession = repository.login(workspace); + newSession = repository().login(workspace); } catch (LoginException e1) { log.warn("Cannot login without credentials: " + e1.getMessage()); // invalid credentials, go to the next step @@ -105,7 +104,7 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, try { SimpleCredentials sc = new SimpleCredentials(defaultUsername, defaultPassword.toCharArray()); - newSession = repository.login(sc, workspace); + newSession = repository().login(sc, workspace); } catch (RepositoryException e) { throw new ArgeoException("Cannot log in to repository", e); } @@ -126,22 +125,22 @@ 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() + if (log.isTraceEnabled()) + log.trace("Cleaning up " + activeSessions.size() + " active JCR sessions..."); deactivate(); for (Session sess : activeSessions.values()) { - sess.logout(); + JcrUtils.logoutQuietly(sess); } activeSessions.clear(); } @@ -173,8 +172,8 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, Session session = activeSessions.get(thread.getId()); activeSessions.remove(thread.getId()); session.logout(); - if (log.isDebugEnabled()) - log.debug("Cleaned up JCR session (userID=" + if (log.isTraceEnabled()) + log.trace("Cleaned up JCR session (userID=" + session.getUserID() + ") from dead thread " + thread.getId()); } @@ -205,10 +204,36 @@ public class ThreadBoundJcrSessionFactory implements FactoryBean, return session; } + protected Repository repository() { + if (repository != null) + return repository; + if (repositories != null) { + // hardened for OSGi dynamic services + Iterator it = repositories.iterator(); + if (it.hasNext()) + return it.next(); + } + throw new ArgeoException("No repository injected"); + } + + // /** Useful for declarative registration of OSGi services (blueprint) */ + // public void register(Repository repository, Map params) { + // this.repository = repository; + // } + // + // /** Useful for declarative registration of OSGi services (blueprint) */ + // public void unregister(Repository repository, Map params) { + // this.repository = null; + // } + public void setRepository(Repository repository) { this.repository = repository; } + public void setRepositories(List repositories) { + this.repositories = repositories; + } + public void setDefaultUsername(String defaultUsername) { this.defaultUsername = defaultUsername; } @@ -228,7 +253,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 @@ -238,7 +263,17 @@ 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())) { session.remove(); Thread thread = Thread.currentThread(); @@ -255,6 +290,10 @@ 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()) {