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
.ArgeoJcrUtils
;
44 import org
.argeo
.jcr
.ArgeoNames
;
45 import org
.argeo
.jcr
.JcrUtils
;
48 * Implements an open session in view patter: a new JCR session is created for
51 public class SimpleSessionProvider
implements SessionProvider
, Serializable
{
52 private static final long serialVersionUID
= 2270957712453841368L;
54 private final static Log log
= LogFactory
55 .getLog(SimpleSessionProvider
.class);
57 private transient Map
<String
, Session
> sessions
;
59 private Boolean openSessionInView
= true;
61 private String securityWorkspace
= "security";
63 public Session
getSession(HttpServletRequest request
, Repository rep
,
64 String workspace
) throws LoginException
, ServletException
,
67 if (openSessionInView
) {
68 JackrabbitSession session
= (JackrabbitSession
) rep
70 if (session
.getWorkspace().getName().equals(securityWorkspace
))
71 writeRemoteRoles(session
);
74 // since sessions is transient it can't be restored from the session
76 sessions
= Collections
77 .synchronizedMap(new HashMap
<String
, Session
>());
79 if (!sessions
.containsKey(workspace
)) {
81 JackrabbitSession session
= (JackrabbitSession
) rep
.login(
83 if (session
.getWorkspace().getName()
84 .equals(securityWorkspace
))
85 writeRemoteRoles(session
);
86 if (log
.isTraceEnabled())
87 log
.trace("User " + session
.getUserID()
88 + " logged into " + request
.getServletPath());
89 sessions
.put(workspace
, session
);
91 } catch (Exception e
) {
92 throw new ArgeoException("Cannot open session", e
);
95 Session session
= sessions
.get(workspace
);
96 if (!session
.isLive()) {
97 sessions
.remove(workspace
);
98 session
= rep
.login(null, workspace
);
99 sessions
.put(workspace
, session
);
106 protected void writeRemoteRoles(JackrabbitSession session
)
107 throws RepositoryException
{
109 String userId
= session
.getUserID();
110 UserManager userManager
= session
.getUserManager();
111 User user
= (User
) userManager
.getAuthorizable(userId
);
116 List
<String
> userGroupIds
= new ArrayList
<String
>();
118 for (Iterator
<Group
> it
= user
.memberOf(); it
.hasNext();)
119 userGroupIds
.add(it
.next().getID());
121 // write roles if needed
122 Node userProfile
= ArgeoJcrUtils
.getUserHome(session
).getNode(
123 ArgeoNames
.ARGEO_PROFILE
);
124 boolean writeRoles
= false;
125 if (userProfile
.hasProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
)) {
126 Value
[] roles
= userProfile
.getProperty(
127 ArgeoNames
.ARGEO_REMOTE_ROLES
).getValues();
128 if (roles
.length
!= userGroupIds
.size())
131 for (int i
= 0; i
< roles
.length
; i
++)
132 if (!roles
[i
].getString().equals(userGroupIds
.get(i
)))
138 session
.getWorkspace().getVersionManager()
139 .checkout(userProfile
.getPath());
140 String
[] roleIds
= userGroupIds
.toArray(new String
[userGroupIds
142 userProfile
.setProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
, roleIds
);
143 JcrUtils
.updateLastModified(userProfile
);
145 session
.getWorkspace().getVersionManager()
146 .checkin(userProfile
.getPath());
151 public void releaseSession(Session session
) {
152 if (log
.isTraceEnabled())
153 log
.trace("Releasing JCR session " + session
);
154 if (openSessionInView
) {
155 if (session
.isLive()) {
157 if (log
.isTraceEnabled())
158 log
.trace("Logged out remote JCR session " + session
);
166 public void destroy() {
167 if (sessions
!= null)
168 for (String workspace
: sessions
.keySet()) {
169 Session session
= sessions
.get(workspace
);
170 if (session
.isLive()) {
172 if (log
.isDebugEnabled())
173 log
.debug("Logged out remote JCR session " + session
);
179 * If set to true a new session will be created each time (the default),
180 * otherwise a single session is cached by workspace and the object should
181 * be of scope session (not supported)
183 public void setOpenSessionInView(Boolean openSessionInView
) {
184 this.openSessionInView
= openSessionInView
;
187 public void setSecurityWorkspace(String securityWorkspace
) {
188 this.securityWorkspace
= securityWorkspace
;