]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/ThreadBoundJcrSessionFactory.java
Improve JCR
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr / src / main / java / org / argeo / jcr / ThreadBoundJcrSessionFactory.java
1 package org.argeo.jcr;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Proxy;
6 import java.util.ArrayList;
7 import java.util.Collections;
8 import java.util.List;
9
10 import javax.jcr.Repository;
11 import javax.jcr.RepositoryException;
12 import javax.jcr.Session;
13 import javax.jcr.SimpleCredentials;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.argeo.ArgeoException;
18 import org.springframework.beans.factory.DisposableBean;
19 import org.springframework.beans.factory.FactoryBean;
20
21 public class ThreadBoundJcrSessionFactory implements FactoryBean,
22 DisposableBean {
23 private final static Log log = LogFactory
24 .getLog(ThreadBoundJcrSessionFactory.class);
25
26 private Repository repository;
27 private List<Session> activeSessions = Collections
28 .synchronizedList(new ArrayList<Session>());
29
30 private ThreadLocal<Session> session = new ThreadLocal<Session>();
31 private boolean destroying = false;
32 private final Session proxiedSession;
33
34 public ThreadBoundJcrSessionFactory() {
35 Class<?>[] interfaces = { Session.class };
36 proxiedSession = (Session) Proxy.newProxyInstance(getClass()
37 .getClassLoader(), interfaces, new InvocationHandler() {
38
39 public Object invoke(Object proxy, Method method, Object[] args)
40 throws Throwable {
41 Session threadSession = session.get();
42 if (threadSession == null) {
43 if ("logout".equals(method.getName()))// no need to login
44 return Void.TYPE;
45 threadSession = login();
46 session.set(threadSession);
47 }
48
49 Object ret = method.invoke(threadSession, args);
50 if ("logout".equals(method.getName())) {
51 session.remove();
52 if (!destroying)
53 activeSessions.remove(threadSession);
54 if (log.isTraceEnabled())
55 log.trace("Logged out from JCR session "
56 + threadSession + "; userId="
57 + threadSession.getUserID());
58 }
59 return ret;
60 }
61 });
62 }
63
64 protected Session login() {
65 try {
66 SimpleCredentials sc = new SimpleCredentials("demo", "demo"
67 .toCharArray());
68 Session sess = repository.login(sc);
69 if (log.isTraceEnabled())
70 log.trace("Log in to JCR session " + sess + "; userId="
71 + sess.getUserID());
72 // Thread.dumpStack();
73 activeSessions.add(sess);
74 return sess;
75 } catch (RepositoryException e) {
76 throw new ArgeoException("Cannot log in to repository", e);
77 }
78 }
79
80 public Object getObject() {
81 return proxiedSession;
82 }
83
84 public void destroy() throws Exception {
85 if (log.isDebugEnabled())
86 log.debug("Cleaning up " + activeSessions.size()
87 + " active JCR sessions...");
88
89 destroying = true;
90 for (Session sess : activeSessions) {
91 sess.logout();
92 }
93 activeSessions.clear();
94 }
95
96 public Class<? extends Session> getObjectType() {
97 return Session.class;
98 }
99
100 public boolean isSingleton() {
101 return true;
102 }
103
104 public void setRepository(Repository repository) {
105 this.repository = repository;
106 }
107
108 }