]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.server.jcr.mvc/src/org/argeo/jackrabbit/remote/SimpleSessionProvider.java
Reduce CMS size
[lgpl/argeo-commons.git] / org.argeo.server.jcr.mvc / src / org / argeo / jackrabbit / remote / SimpleSessionProvider.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.jackrabbit.remote;
17
18 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25
26 import javax.jcr.LoginException;
27 import javax.jcr.Node;
28 import javax.jcr.Repository;
29 import javax.jcr.RepositoryException;
30 import javax.jcr.Session;
31 import javax.jcr.Value;
32 import javax.servlet.ServletException;
33 import javax.servlet.http.HttpServletRequest;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.jackrabbit.api.JackrabbitSession;
38 import org.apache.jackrabbit.api.security.user.Group;
39 import org.apache.jackrabbit.api.security.user.User;
40 import org.apache.jackrabbit.api.security.user.UserManager;
41 import org.apache.jackrabbit.server.SessionProvider;
42 import org.argeo.ArgeoException;
43 import org.argeo.jcr.ArgeoNames;
44 import org.argeo.jcr.JcrUtils;
45 import org.argeo.jcr.UserJcrUtils;
46
47 /**
48 * Implements an open session in view patter: a new JCR session is created for
49 * each request
50 *
51 * @deprecated use {@link ScopedSessionProvider} or
52 * {@link OpenInViewSessionProvider}
53 */
54 @Deprecated
55 public class SimpleSessionProvider implements SessionProvider, Serializable {
56 private static final long serialVersionUID = 2270957712453841368L;
57
58 private final static Log log = LogFactory
59 .getLog(SimpleSessionProvider.class);
60
61 private transient Map<String, Session> sessions;
62
63 private Boolean openSessionInView = true;
64
65 private String defaultWorkspace = "default";
66
67 private String webSessionId = null;
68
69 public Session getSession(HttpServletRequest request, Repository rep,
70 String workspace) throws LoginException, ServletException,
71 RepositoryException {
72
73 if (openSessionInView) {
74 JackrabbitSession session = (JackrabbitSession) login(request, rep,
75 workspace);
76 if (session.getWorkspace().getName().equals(defaultWorkspace))
77 writeRemoteRoles(session);
78 return session;
79 } else {
80 if (webSessionId != null
81 && !webSessionId.equals(request.getSession().getId()))
82 throw new ArgeoException(
83 "Only session scope is supported in this mode");
84 webSessionId = request.getSession().getId();
85
86 // since sessions is transient it can't be restored from the session
87 if (sessions == null)
88 sessions = Collections
89 .synchronizedMap(new HashMap<String, Session>());
90
91 if (!sessions.containsKey(workspace)) {
92 try {
93 // JackrabbitSession session = (JackrabbitSession)
94 // rep.login(
95 // null, workspace);
96 JackrabbitSession session = (JackrabbitSession) login(
97 request, rep, workspace);
98 if (session.getWorkspace().getName()
99 .equals(defaultWorkspace))
100 writeRemoteRoles(session);
101 if (log.isTraceEnabled())
102 log.trace("User " + session.getUserID()
103 + " logged into " + request.getServletPath());
104 sessions.put(workspace, session);
105 return session;
106 } catch (Exception e) {
107 throw new ArgeoException("Cannot open session", e);
108 }
109 } else {
110 Session session = sessions.get(workspace);
111 if (!session.isLive()) {
112 sessions.remove(workspace);
113 session = login(request, rep, workspace);
114 sessions.put(workspace, session);
115 }
116 return session;
117 }
118 }
119 }
120
121 protected Session login(HttpServletRequest request, Repository repository,
122 String workspace) throws RepositoryException {
123 if (log.isDebugEnabled())
124 log.debug("Login to workspace "
125 + (workspace == null ? "<default>" : workspace)
126 + " in web session " + request.getSession().getId());
127 return repository.login(workspace);
128 }
129
130 protected void writeRemoteRoles(JackrabbitSession session)
131 throws RepositoryException {
132 // FIXME better deal w/ non node repo
133
134 // retrieve roles
135 String userId = session.getUserID();
136 UserManager userManager = session.getUserManager();
137 User user = (User) userManager.getAuthorizable(userId);
138 if (user == null) {
139 // anonymous
140 return;
141 }
142 List<String> userGroupIds = new ArrayList<String>();
143 if (user != null)
144 for (Iterator<Group> it = user.memberOf(); it.hasNext();)
145 userGroupIds.add(it.next().getID());
146
147 // write roles if needed
148 Node userHome = UserJcrUtils.getUserHome(session);
149 boolean writeRoles = false;
150 if (userHome.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
151 Value[] roles = userHome.getProperty(ArgeoNames.ARGEO_REMOTE_ROLES)
152 .getValues();
153 if (roles.length != userGroupIds.size())
154 writeRoles = true;
155 else
156 for (int i = 0; i < roles.length; i++)
157 if (!roles[i].getString().equals(userGroupIds.get(i)))
158 writeRoles = true;
159 } else
160 writeRoles = true;
161
162 if (writeRoles) {
163 session.getWorkspace().getVersionManager()
164 .checkout(userHome.getPath());
165 String[] roleIds = userGroupIds.toArray(new String[userGroupIds
166 .size()]);
167 userHome.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds);
168 JcrUtils.updateLastModified(userHome);
169 session.save();
170 session.getWorkspace().getVersionManager()
171 .checkin(userHome.getPath());
172 }
173
174 }
175
176 public void releaseSession(Session session) {
177 if (log.isTraceEnabled())
178 log.trace("Releasing JCR session " + session);
179 if (openSessionInView) {
180 JcrUtils.logoutQuietly(session);
181 if (log.isDebugEnabled())
182 log.debug("Logged out remote JCR session " + session);
183 }
184 }
185
186 public void init() {
187 if (log.isDebugEnabled())
188 log.debug("Init session provider for web session " + webSessionId);
189 }
190
191 public void destroy() {
192 if (log.isDebugEnabled())
193 log.debug("Destroy session provider for web session "
194 + webSessionId);
195
196 if (sessions != null)
197 for (String workspace : sessions.keySet()) {
198 Session session = sessions.get(workspace);
199 JcrUtils.logoutQuietly(session);
200 }
201 }
202
203 /**
204 * If set to true a new session will be created each time (the default),
205 * otherwise a single session is cached by workspace and the object should
206 * be of scope session (not supported)
207 */
208 public void setOpenSessionInView(Boolean openSessionInView) {
209 this.openSessionInView = openSessionInView;
210 }
211
212 public void setSecurityWorkspace(String securityWorkspace) {
213 this.defaultWorkspace = securityWorkspace;
214 }
215
216 }