2 * Copyright (C) 2007-2012 Mathieu Baudier
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
;
47 * Implements an open session in view patter: a new JCR session is created for
50 public class SimpleSessionProvider
implements SessionProvider
, Serializable
{
51 private static final long serialVersionUID
= 2270957712453841368L;
53 private final static Log log
= LogFactory
54 .getLog(SimpleSessionProvider
.class);
56 private transient Map
<String
, Session
> sessions
;
58 private Boolean openSessionInView
= true;
60 private String securityWorkspace
= "security";
62 public Session
getSession(HttpServletRequest request
, Repository rep
,
63 String workspace
) throws LoginException
, ServletException
,
66 if (openSessionInView
) {
67 JackrabbitSession session
= (JackrabbitSession
) rep
69 if (session
.getWorkspace().getName().equals(securityWorkspace
))
70 writeRemoteRoles(session
);
73 // since sessions is transient it can't be restored from the session
75 sessions
= Collections
76 .synchronizedMap(new HashMap
<String
, Session
>());
78 if (!sessions
.containsKey(workspace
)) {
80 JackrabbitSession session
= (JackrabbitSession
) rep
.login(
82 if (session
.getWorkspace().getName()
83 .equals(securityWorkspace
))
84 writeRemoteRoles(session
);
85 if (log
.isTraceEnabled())
86 log
.trace("User " + session
.getUserID()
87 + " logged into " + request
.getServletPath());
88 sessions
.put(workspace
, session
);
90 } catch (Exception e
) {
91 throw new ArgeoException("Cannot open session", e
);
94 Session session
= sessions
.get(workspace
);
95 if (!session
.isLive()) {
96 sessions
.remove(workspace
);
97 session
= rep
.login(null, workspace
);
98 sessions
.put(workspace
, session
);
105 protected void writeRemoteRoles(JackrabbitSession session
)
106 throws RepositoryException
{
108 String userId
= session
.getUserID();
109 UserManager userManager
= session
.getUserManager();
110 User user
= (User
) userManager
.getAuthorizable(userId
);
115 List
<String
> userGroupIds
= new ArrayList
<String
>();
117 for (Iterator
<Group
> it
= user
.memberOf(); it
.hasNext();)
118 userGroupIds
.add(it
.next().getID());
120 // write roles if needed
121 Node userProfile
= JcrUtils
.getUserHome(session
).getNode(
122 ArgeoNames
.ARGEO_PROFILE
);
123 boolean writeRoles
= false;
124 if (userProfile
.hasProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
)) {
125 Value
[] roles
= userProfile
.getProperty(
126 ArgeoNames
.ARGEO_REMOTE_ROLES
).getValues();
127 if (roles
.length
!= userGroupIds
.size())
130 for (int i
= 0; i
< roles
.length
; i
++)
131 if (!roles
[i
].getString().equals(userGroupIds
.get(i
)))
137 session
.getWorkspace().getVersionManager()
138 .checkout(userProfile
.getPath());
139 String
[] roleIds
= userGroupIds
.toArray(new String
[userGroupIds
141 userProfile
.setProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
, roleIds
);
142 JcrUtils
.updateLastModified(userProfile
);
144 session
.getWorkspace().getVersionManager()
145 .checkin(userProfile
.getPath());
150 public void releaseSession(Session session
) {
151 if (log
.isTraceEnabled())
152 log
.trace("Releasing JCR session " + session
);
153 if (openSessionInView
) {
154 if (session
.isLive()) {
156 if (log
.isTraceEnabled())
157 log
.trace("Logged out remote JCR session " + session
);
165 public void destroy() {
166 if (sessions
!= null)
167 for (String workspace
: sessions
.keySet()) {
168 Session session
= sessions
.get(workspace
);
169 if (session
.isLive()) {
171 if (log
.isDebugEnabled())
172 log
.debug("Logged out remote JCR session " + session
);
178 * If set to true a new session will be created each time (the default),
179 * otherwise a single session is cached by workspace and the object should
180 * be of scope session (not supported)
182 public void setOpenSessionInView(Boolean openSessionInView
) {
183 this.openSessionInView
= openSessionInView
;
186 public void setSecurityWorkspace(String securityWorkspace
) {
187 this.securityWorkspace
= securityWorkspace
;