/*
* (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* bstefanescu
*/
package org.nuxeo.ecm.automation;
import java.util.ArrayList;
import java.util.List;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.nuxeo.ecm.core.api.CoreInstance;
import org.nuxeo.ecm.core.api.CoreSession;
/**
* @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
*/
public class LoginStack {
protected List<Entry> stack = new ArrayList<Entry>();
protected CoreSession originalSession;
protected CoreSession currentSession;
public LoginStack(CoreSession session) {
setSession(session);
}
public void setSession(CoreSession session) {
originalSession = session;
currentSession = session;
}
/**
* Get the current session
*
* @return
*/
public CoreSession getSession() {
return currentSession;
}
public void push(LoginContext lc) {
Entry entry = new Entry(lc);
String repositoryName;
if (originalSession != null) {
repositoryName = originalSession.getRepositoryName();
} else {
repositoryName = null; // default repository
}
entry.session = CoreInstance.openCoreSession(repositoryName);
currentSession = entry.session;
stack.add(entry);
}
public Entry peek() {
if (!stack.isEmpty()) {
return stack.get(stack.size() - 1);
}
return null;
}
/**
* Remove the current login context from the stack.
* <p>
* If no login context in in the stack nothing is done. If the login context has an associated CoreSession the
* session will be destroyed and the previous session is restored as the active session of the operation context.
*/
public void pop() throws OperationException {
if (!stack.isEmpty()) {
Entry entry = stack.remove(stack.size() - 1);
entry.dispose();
entry = peek();
if (entry != null) {
currentSession = entry.session;
} else {
currentSession = originalSession;
}
}
}
/**
* Remove the stacked logins if any. This is called when chain execution is done.
*/
protected void clear() throws OperationException {
if (!stack.isEmpty()) {
for (int i = stack.size() - 1; i > -1; i--) {
stack.get(i).dispose();
}
stack.clear();
currentSession = originalSession;
stack.clear();
}
}
public static class Entry {
public LoginContext lc;
public CoreSession session;
public Entry(LoginContext lc) {
this(lc, null);
}
public Entry(LoginContext lc, CoreSession session) {
this.lc = lc;
this.session = session;
}
public final boolean hasSession() {
return session != null;
}
public final void dispose() throws OperationException {
try {
if (session != null) {
try {
session.save();
} finally {
session.close();
}
}
} finally {
try {
session = null;
lc.logout();
lc = null;
} catch (LoginException e) {
throw new OperationException(e);
}
}
}
}
}