X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.server.jackrabbit%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fjackrabbit%2Fremote%2FSimpleSessionProvider.java;fp=org.argeo.server.jackrabbit%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fjackrabbit%2Fremote%2FSimpleSessionProvider.java;h=1d438d5044561218e0dd6258f4656495d3794c53;hb=1df1bf64759d35d3d72b9d96b26b71118fdbe031;hp=0000000000000000000000000000000000000000;hpb=3a3d316af102ba410d1d9e6de349d0c8f7ac044f;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/remote/SimpleSessionProvider.java b/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/remote/SimpleSessionProvider.java new file mode 100644 index 000000000..1d438d504 --- /dev/null +++ b/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/remote/SimpleSessionProvider.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.jackrabbit.remote; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.jcr.LoginException; +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Value; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jackrabbit.api.JackrabbitSession; +import org.apache.jackrabbit.api.security.user.Group; +import org.apache.jackrabbit.api.security.user.User; +import org.apache.jackrabbit.api.security.user.UserManager; +import org.apache.jackrabbit.server.SessionProvider; +import org.argeo.ArgeoException; +import org.argeo.jcr.ArgeoNames; +import org.argeo.jcr.JcrUtils; +import org.argeo.jcr.UserJcrUtils; + +/** + * Implements an open session in view patter: a new JCR session is created for + * each request + * + * @deprecated use {@link ScopedSessionProvider} or + * {@link OpenInViewSessionProvider} + */ +@Deprecated +public class SimpleSessionProvider implements SessionProvider, Serializable { + private static final long serialVersionUID = 2270957712453841368L; + + private final static Log log = LogFactory + .getLog(SimpleSessionProvider.class); + + private transient Map sessions; + + private Boolean openSessionInView = true; + + private String defaultWorkspace = "default"; + + private String webSessionId = null; + + public Session getSession(HttpServletRequest request, Repository rep, + String workspace) throws LoginException, ServletException, + RepositoryException { + + if (openSessionInView) { + JackrabbitSession session = (JackrabbitSession) login(request, rep, + workspace); + if (session.getWorkspace().getName().equals(defaultWorkspace)) + writeRemoteRoles(session); + return session; + } else { + if (webSessionId != null + && !webSessionId.equals(request.getSession().getId())) + throw new ArgeoException( + "Only session scope is supported in this mode"); + webSessionId = request.getSession().getId(); + + // since sessions is transient it can't be restored from the session + if (sessions == null) + sessions = Collections + .synchronizedMap(new HashMap()); + + if (!sessions.containsKey(workspace)) { + try { + // JackrabbitSession session = (JackrabbitSession) + // rep.login( + // null, workspace); + JackrabbitSession session = (JackrabbitSession) login( + request, rep, workspace); + if (session.getWorkspace().getName() + .equals(defaultWorkspace)) + writeRemoteRoles(session); + if (log.isTraceEnabled()) + log.trace("User " + session.getUserID() + + " logged into " + request.getServletPath()); + sessions.put(workspace, session); + return session; + } catch (Exception e) { + throw new ArgeoException("Cannot open session", e); + } + } else { + Session session = sessions.get(workspace); + if (!session.isLive()) { + sessions.remove(workspace); + session = login(request, rep, workspace); + sessions.put(workspace, session); + } + return session; + } + } + } + + protected Session login(HttpServletRequest request, Repository repository, + String workspace) throws RepositoryException { + if (log.isDebugEnabled()) + log.debug("Login to workspace " + + (workspace == null ? "" : workspace) + + " in web session " + request.getSession().getId()); + return repository.login(workspace); + } + + protected void writeRemoteRoles(JackrabbitSession session) + throws RepositoryException { + // FIXME better deal w/ non node repo + + // retrieve roles + String userId = session.getUserID(); + UserManager userManager = session.getUserManager(); + User user = (User) userManager.getAuthorizable(userId); + if (user == null) { + // anonymous + return; + } + List userGroupIds = new ArrayList(); + if (user != null) + for (Iterator it = user.memberOf(); it.hasNext();) + userGroupIds.add(it.next().getID()); + + // write roles if needed + Node userHome = UserJcrUtils.getUserHome(session); + boolean writeRoles = false; + if (userHome.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) { + Value[] roles = userHome.getProperty(ArgeoNames.ARGEO_REMOTE_ROLES) + .getValues(); + if (roles.length != userGroupIds.size()) + writeRoles = true; + else + for (int i = 0; i < roles.length; i++) + if (!roles[i].getString().equals(userGroupIds.get(i))) + writeRoles = true; + } else + writeRoles = true; + + if (writeRoles) { + session.getWorkspace().getVersionManager() + .checkout(userHome.getPath()); + String[] roleIds = userGroupIds.toArray(new String[userGroupIds + .size()]); + userHome.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds); + JcrUtils.updateLastModified(userHome); + session.save(); + session.getWorkspace().getVersionManager() + .checkin(userHome.getPath()); + } + + } + + public void releaseSession(Session session) { + if (log.isTraceEnabled()) + log.trace("Releasing JCR session " + session); + if (openSessionInView) { + JcrUtils.logoutQuietly(session); + if (log.isDebugEnabled()) + log.debug("Logged out remote JCR session " + session); + } + } + + public void init() { + if (log.isDebugEnabled()) + log.debug("Init session provider for web session " + webSessionId); + } + + public void destroy() { + if (log.isDebugEnabled()) + log.debug("Destroy session provider for web session " + + webSessionId); + + if (sessions != null) + for (String workspace : sessions.keySet()) { + Session session = sessions.get(workspace); + JcrUtils.logoutQuietly(session); + } + } + + /** + * If set to true a new session will be created each time (the default), + * otherwise a single session is cached by workspace and the object should + * be of scope session (not supported) + */ + public void setOpenSessionInView(Boolean openSessionInView) { + this.openSessionInView = openSessionInView; + } + + public void setSecurityWorkspace(String securityWorkspace) { + this.defaultWorkspace = securityWorkspace; + } + +}