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
;
45 import org
.argeo
.jcr
.UserJcrUtils
;
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 defaultWorkspace
= "default";
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(defaultWorkspace
))
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(defaultWorkspace
))
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
{
108 // FIXME better deal w/ non node repo
111 String userId
= session
.getUserID();
112 UserManager userManager
= session
.getUserManager();
113 User user
= (User
) userManager
.getAuthorizable(userId
);
118 List
<String
> userGroupIds
= new ArrayList
<String
>();
120 for (Iterator
<Group
> it
= user
.memberOf(); it
.hasNext();)
121 userGroupIds
.add(it
.next().getID());
123 // write roles if needed
124 Node userHome
= UserJcrUtils
.getUserHome(session
);
125 boolean writeRoles
= false;
126 if (userHome
.hasProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
)) {
127 Value
[] roles
= userHome
.getProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
)
129 if (roles
.length
!= userGroupIds
.size())
132 for (int i
= 0; i
< roles
.length
; i
++)
133 if (!roles
[i
].getString().equals(userGroupIds
.get(i
)))
139 session
.getWorkspace().getVersionManager()
140 .checkout(userHome
.getPath());
141 String
[] roleIds
= userGroupIds
.toArray(new String
[userGroupIds
143 userHome
.setProperty(ArgeoNames
.ARGEO_REMOTE_ROLES
, roleIds
);
144 JcrUtils
.updateLastModified(userHome
);
146 session
.getWorkspace().getVersionManager()
147 .checkin(userHome
.getPath());
152 public void releaseSession(Session session
) {
153 if (log
.isTraceEnabled())
154 log
.trace("Releasing JCR session " + session
);
155 if (openSessionInView
) {
156 if (session
.isLive()) {
158 if (log
.isTraceEnabled())
159 log
.trace("Logged out remote JCR session " + session
);
167 public void destroy() {
168 if (sessions
!= null)
169 for (String workspace
: sessions
.keySet()) {
170 Session session
= sessions
.get(workspace
);
171 if (session
.isLive()) {
173 if (log
.isDebugEnabled())
174 log
.debug("Logged out remote JCR session " + session
);
180 * If set to true a new session will be created each time (the default),
181 * otherwise a single session is cached by workspace and the object should
182 * be of scope session (not supported)
184 public void setOpenSessionInView(Boolean openSessionInView
) {
185 this.openSessionInView
= openSessionInView
;
188 public void setSecurityWorkspace(String securityWorkspace
) {
189 this.defaultWorkspace
= securityWorkspace
;