]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/remote/SimpleSessionProvider.java
First working remote node
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jackrabbit / src / main / java / org / argeo / jackrabbit / remote / SimpleSessionProvider.java
1 package org.argeo.jackrabbit.remote;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.jcr.LoginException;
12 import javax.jcr.Node;
13 import javax.jcr.Repository;
14 import javax.jcr.RepositoryException;
15 import javax.jcr.Session;
16 import javax.jcr.Value;
17 import javax.servlet.ServletException;
18 import javax.servlet.http.HttpServletRequest;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.jackrabbit.api.JackrabbitSession;
23 import org.apache.jackrabbit.api.security.user.Group;
24 import org.apache.jackrabbit.api.security.user.User;
25 import org.apache.jackrabbit.api.security.user.UserManager;
26 import org.apache.jackrabbit.server.SessionProvider;
27 import org.argeo.ArgeoException;
28 import org.argeo.jcr.ArgeoNames;
29 import org.argeo.jcr.JcrUtils;
30
31 /**
32 * To be injected, typically of scope="session". Implements an open session in
33 * view patter: a new JCR session is created for each request
34 */
35 public class SimpleSessionProvider implements SessionProvider, Serializable {
36 private static final long serialVersionUID = 2270957712453841368L;
37
38 private final static Log log = LogFactory
39 .getLog(SimpleSessionProvider.class);
40
41 private transient Map<String, Session> sessions;
42
43 private Boolean openSessionInView = true;
44
45 public Session getSession(HttpServletRequest request, Repository rep,
46 String workspace) throws LoginException, ServletException,
47 RepositoryException {
48
49 if (openSessionInView) {
50 JackrabbitSession session = (JackrabbitSession) rep
51 .login(workspace);
52 writeRemoteRoles(session);
53 return session;
54 } else {
55 // since sessions is transient it can't be restored from the session
56 if (sessions == null)
57 sessions = Collections
58 .synchronizedMap(new HashMap<String, Session>());
59
60 if (!sessions.containsKey(workspace)) {
61 try {
62 JackrabbitSession session = (JackrabbitSession) rep.login(
63 null, workspace);
64 writeRemoteRoles(session);
65 if (log.isTraceEnabled())
66 log.trace("User " + session.getUserID()
67 + " logged into " + request.getServletPath());
68 sessions.put(workspace, session);
69 return session;
70 } catch (Exception e) {
71 throw new ArgeoException("Cannot open session", e);
72 }
73 } else {
74 Session session = sessions.get(workspace);
75 if (!session.isLive()) {
76 sessions.remove(workspace);
77 session = rep.login(null, workspace);
78 sessions.put(workspace, session);
79 }
80 return session;
81 }
82 }
83 }
84
85 protected void writeRemoteRoles(JackrabbitSession session)
86 throws RepositoryException {
87 // retrieve roles
88 String userId = session.getUserID();
89 UserManager userManager = session.getUserManager();
90 User user = (User) userManager.getAuthorizable(userId);
91 if (user == null) {
92 // anonymous
93 return;
94 }
95 List<String> userGroupIds = new ArrayList<String>();
96 if (user != null)
97 for (Iterator<Group> it = user.memberOf(); it.hasNext();)
98 userGroupIds.add(it.next().getID());
99
100 // write roles if needed
101 Node userProfile = JcrUtils.getUserProfile(session);
102 boolean writeRoles = false;
103 if (userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
104 Value[] roles = userProfile.getProperty(
105 ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
106 if (roles.length != userGroupIds.size())
107 writeRoles = true;
108 else
109 for (int i = 0; i < roles.length; i++)
110 if (!roles[i].getString().equals(userGroupIds.get(i)))
111 writeRoles = true;
112 } else
113 writeRoles = true;
114
115 if (writeRoles) {
116 session.getWorkspace().getVersionManager()
117 .checkout(userProfile.getPath());
118 String[] roleIds = userGroupIds.toArray(new String[userGroupIds
119 .size()]);
120 userProfile.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds);
121 JcrUtils.updateLastModified(userProfile);
122 session.save();
123 session.getWorkspace().getVersionManager()
124 .checkin(userProfile.getPath());
125 }
126
127 }
128
129 public void releaseSession(Session session) {
130 if (log.isTraceEnabled())
131 log.trace("Releasing JCR session " + session);
132 if (openSessionInView) {
133 if (session.isLive()) {
134 session.logout();
135 if (log.isTraceEnabled())
136 log.trace("Logged out remote JCR session " + session);
137 }
138 }
139 }
140
141 public void init() {
142 }
143
144 public void dispose() {
145 if (sessions != null)
146 for (String workspace : sessions.keySet()) {
147 Session session = sessions.get(workspace);
148 if (session.isLive()) {
149 session.logout();
150 if (log.isDebugEnabled())
151 log.debug("Logged out remote JCR session " + session);
152 }
153 }
154 }
155 }