]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/remote/SimpleSessionProvider.java
Fix issue with default workspace
[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 * Implements an open session in view patter: a new JCR session is created for
33 * 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 private String securityWorkspace = "security";
46
47 public Session getSession(HttpServletRequest request, Repository rep,
48 String workspace) throws LoginException, ServletException,
49 RepositoryException {
50
51 if (openSessionInView) {
52 JackrabbitSession session = (JackrabbitSession) rep
53 .login(workspace);
54 if (session.getWorkspace().getName().equals(securityWorkspace))
55 writeRemoteRoles(session);
56 return session;
57 } else {
58 // since sessions is transient it can't be restored from the session
59 if (sessions == null)
60 sessions = Collections
61 .synchronizedMap(new HashMap<String, Session>());
62
63 if (!sessions.containsKey(workspace)) {
64 try {
65 JackrabbitSession session = (JackrabbitSession) rep.login(
66 null, workspace);
67 if (session.getWorkspace().getName()
68 .equals(securityWorkspace))
69 writeRemoteRoles(session);
70 if (log.isTraceEnabled())
71 log.trace("User " + session.getUserID()
72 + " logged into " + request.getServletPath());
73 sessions.put(workspace, session);
74 return session;
75 } catch (Exception e) {
76 throw new ArgeoException("Cannot open session", e);
77 }
78 } else {
79 Session session = sessions.get(workspace);
80 if (!session.isLive()) {
81 sessions.remove(workspace);
82 session = rep.login(null, workspace);
83 sessions.put(workspace, session);
84 }
85 return session;
86 }
87 }
88 }
89
90 protected void writeRemoteRoles(JackrabbitSession session)
91 throws RepositoryException {
92 // retrieve roles
93 String userId = session.getUserID();
94 UserManager userManager = session.getUserManager();
95 User user = (User) userManager.getAuthorizable(userId);
96 if (user == null) {
97 // anonymous
98 return;
99 }
100 List<String> userGroupIds = new ArrayList<String>();
101 if (user != null)
102 for (Iterator<Group> it = user.memberOf(); it.hasNext();)
103 userGroupIds.add(it.next().getID());
104
105 // write roles if needed
106 Node userProfile = JcrUtils.getUserHome(session).getNode(
107 ArgeoNames.ARGEO_PROFILE);
108 boolean writeRoles = false;
109 if (userProfile.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
110 Value[] roles = userProfile.getProperty(
111 ArgeoNames.ARGEO_REMOTE_ROLES).getValues();
112 if (roles.length != userGroupIds.size())
113 writeRoles = true;
114 else
115 for (int i = 0; i < roles.length; i++)
116 if (!roles[i].getString().equals(userGroupIds.get(i)))
117 writeRoles = true;
118 } else
119 writeRoles = true;
120
121 if (writeRoles) {
122 session.getWorkspace().getVersionManager()
123 .checkout(userProfile.getPath());
124 String[] roleIds = userGroupIds.toArray(new String[userGroupIds
125 .size()]);
126 userProfile.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds);
127 JcrUtils.updateLastModified(userProfile);
128 session.save();
129 session.getWorkspace().getVersionManager()
130 .checkin(userProfile.getPath());
131 }
132
133 }
134
135 public void releaseSession(Session session) {
136 if (log.isTraceEnabled())
137 log.trace("Releasing JCR session " + session);
138 if (openSessionInView) {
139 if (session.isLive()) {
140 session.logout();
141 if (log.isTraceEnabled())
142 log.trace("Logged out remote JCR session " + session);
143 }
144 }
145 }
146
147 public void init() {
148 }
149
150 public void destroy() {
151 if (sessions != null)
152 for (String workspace : sessions.keySet()) {
153 Session session = sessions.get(workspace);
154 if (session.isLive()) {
155 session.logout();
156 if (log.isDebugEnabled())
157 log.debug("Logged out remote JCR session " + session);
158 }
159 }
160 }
161
162 /**
163 * If set to true a new session will be created each time (the default),
164 * otherwise a single session is cached by workspace and the object should
165 * be of scope session (not supported)
166 */
167 public void setOpenSessionInView(Boolean openSessionInView) {
168 this.openSessionInView = openSessionInView;
169 }
170
171 public void setSecurityWorkspace(String securityWorkspace) {
172 this.securityWorkspace = securityWorkspace;
173 }
174
175 }