2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.jackrabbit
.remote
;
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
;
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
;
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
;
48 * Implements an open session in view patter: a new JCR session is created for
51 * @deprecated use {@link ScopedSessionProvider} or
52 * {@link OpenInViewSessionProvider}
55 public class SimpleSessionProvider
implements SessionProvider
, Serializable
{
56 private static final long serialVersionUID
= 2270957712453841368L;
58 private final static Log log
= LogFactory
59 .getLog(SimpleSessionProvider
.class);
61 private transient Map
<String
, Session
> sessions
;
63 private Boolean openSessionInView
= true;
65 private String defaultWorkspace
= "default";
67 private String webSessionId
= null;
69 public Session
getSession(HttpServletRequest request
, Repository rep
,
70 String workspace
) throws LoginException
, ServletException
,
73 if (openSessionInView
) {
74 JackrabbitSession session
= (JackrabbitSession
) login(request
, rep
,
76 if (session
.getWorkspace().getName().equals(defaultWorkspace
))
77 writeRemoteRoles(session
);
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();
86 // since sessions is transient it can't be restored from the session
88 sessions
= Collections
89 .synchronizedMap(new HashMap
<String
, Session
>());
91 if (!sessions
.containsKey(workspace
)) {
93 // JackrabbitSession session = (JackrabbitSession)
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
);
106 } catch (Exception e
) {
107 throw new ArgeoException("Cannot open session", e
);
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
);
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
);
130 protected void writeRemoteRoles(JackrabbitSession session
)
131 throws RepositoryException
{
132 // FIXME better deal w/ non node repo
135 String userId
= session
.getUserID();
136 UserManager userManager
= session
.getUserManager();
137 User user
= (User
) userManager
.getAuthorizable(userId
);
142 List
<String
> userGroupIds
= new ArrayList
<String
>();
144 for (Iterator
<Group
> it
= user
.memberOf(); it
.hasNext();)
145 userGroupIds
.add(it
.next().getID());
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
)
153 if (roles
.length
!= userGroupIds
.size())
156 for (int i
= 0; i
< roles
.length
; i
++)
157 if (!roles
[i
].getString().equals(userGroupIds
.get(i
)))
163 session
.getWorkspace().getVersionManager()
164 .checkout(userHome
.getPath());
165 String
[] roleIds
= userGroupIds
.toArray(new String
[userGroupIds
167 userHome
.setProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
, roleIds
);
168 JcrUtils
.updateLastModified(userHome
);
170 session
.getWorkspace().getVersionManager()
171 .checkin(userHome
.getPath());
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
);
187 if (log
.isDebugEnabled())
188 log
.debug("Init session provider for web session " + webSessionId
);
191 public void destroy() {
192 if (log
.isDebugEnabled())
193 log
.debug("Destroy session provider for web session "
196 if (sessions
!= null)
197 for (String workspace
: sessions
.keySet()) {
198 Session session
= sessions
.get(workspace
);
199 JcrUtils
.logoutQuietly(session
);
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)
208 public void setOpenSessionInView(Boolean openSessionInView
) {
209 this.openSessionInView
= openSessionInView
;
212 public void setSecurityWorkspace(String securityWorkspace
) {
213 this.defaultWorkspace
= securityWorkspace
;