001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.webengine.jaxrs.session.impl; 013 014import java.util.concurrent.locks.ReentrantLock; 015 016import javax.security.auth.login.LoginContext; 017import javax.security.auth.login.LoginException; 018import javax.servlet.http.HttpServletRequest; 019import javax.servlet.http.HttpSession; 020import javax.servlet.http.HttpSessionBindingEvent; 021import javax.servlet.http.HttpSessionBindingListener; 022 023import org.apache.commons.logging.Log; 024import org.apache.commons.logging.LogFactory; 025import org.nuxeo.ecm.core.api.CoreSession; 026import org.nuxeo.ecm.webengine.jaxrs.session.CoreSessionProvider; 027import org.nuxeo.ecm.webengine.jaxrs.session.SessionFactory; 028import org.nuxeo.ecm.webengine.jaxrs.session.SessionRef; 029import org.nuxeo.ecm.webengine.jaxrs.session.impl.PerSessionCoreProvider.Ref; 030import org.nuxeo.runtime.api.Framework; 031 032/** 033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 034 */ 035public class PerSessionCoreProvider extends CoreSessionProvider<Ref> implements HttpSessionBindingListener { 036 037 private static final Log log = LogFactory.getLog(PerSessionCoreProvider.class); 038 039 public static class Ref implements SessionRef { 040 protected CoreSession session; 041 042 protected ReentrantLock lock; 043 044 public Ref(CoreSession session) { 045 this.session = session; 046 this.lock = new ReentrantLock(); 047 } 048 049 @Override 050 public CoreSession get() { 051 lock.lock(); 052 return session; 053 } 054 055 @Override 056 public void unget() { 057 // unlock only if the current thread holds the lock otherwise ignore. 058 try { 059 lock.unlock(); 060 } catch (IllegalMonitorStateException e) { 061 // do nothing 062 } 063 } 064 065 @Override 066 public void destroy() { 067 try { 068 session.close(); 069 } finally { 070 session = null; 071 lock = null; 072 } 073 } 074 075 } 076 077 public static synchronized void install(HttpServletRequest request) { 078 HttpSession s = request.getSession(true); 079 if (s.getAttribute(SessionFactory.SESSION_FACTORY_KEY) == null) { 080 s.setAttribute(SessionFactory.SESSION_FACTORY_KEY, new PerSessionCoreProvider()); 081 } 082 } 083 084 @Override 085 protected Ref createSessionRef(CoreSession session) { 086 return new Ref(session); 087 } 088 089 @Override 090 public void onRequestDone(HttpServletRequest request) { 091 // unlock sessions if any was locked 092 for (SessionRef ref : getSessions()) { 093 ref.unget(); 094 } 095 } 096 097 @Override 098 public void valueBound(HttpSessionBindingEvent event) { 099 // do nothing 100 } 101 102 @Override 103 public void valueUnbound(HttpSessionBindingEvent event) { 104 // destroy all sessions 105 if (!hasSessions()) { 106 destroy(); 107 return; 108 } 109 110 LoginContext lc = null; 111 try { 112 lc = Framework.login(); 113 destroy(); 114 } catch (LoginException e) { 115 log.error(e, e); 116 } finally { 117 if (lc != null) { 118 try { 119 lc.logout(); 120 } catch (LoginException e) { 121 log.error(e, e); 122 } 123 } 124 } 125 } 126 127 @Override 128 public synchronized SessionRef[] getSessions() { 129 return super.getSessions(); 130 } 131 132 @Override 133 public synchronized SessionRef getSessionRef(HttpServletRequest request, String repoName) { 134 return super.getSessionRef(request, repoName); 135 } 136 137 @Override 138 public synchronized boolean hasSessions() { 139 return super.hasSessions(); 140 } 141 142 @Override 143 protected synchronized void destroy() { 144 super.destroy(); 145 } 146 147}