/*
* (C) Copyright 2014 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.
*/
package org.nuxeo.runtime.api.login;
import java.util.concurrent.atomic.AtomicInteger;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import org.apache.commons.logging.LogFactory;
public class LoginConfiguration extends Configuration {
public static final LoginConfiguration INSTANCE = new LoginConfiguration();
protected final AtomicInteger counter = new AtomicInteger(0);
public interface Provider {
public AppConfigurationEntry[] getAppConfigurationEntry(String name);
}
protected final InheritableThreadLocal<Provider> holder = new InheritableThreadLocal<Provider>() {
@Override
protected Provider initialValue() {
return context.provider;
};
};
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
AppConfigurationEntry[] appConfigurationEntry = holder.get().getAppConfigurationEntry(name);
if (appConfigurationEntry == null) {
appConfigurationEntry = context.parent.getAppConfigurationEntry(name);
}
return appConfigurationEntry;
}
@Override
public void refresh() {
context.parent.refresh();
}
protected class InstallContext {
protected final Configuration parent = Configuration.getConfiguration();
protected final Provider provider;
protected final Thread thread = Thread.currentThread();
protected final Throwable stacktrace = new Throwable();
protected InstallContext(Provider provider) {
this.provider = provider;
}
@Override
public String toString() {
return "Login Installation Context [parent=" + parent + ", thread=" + thread + "]";
}
}
protected InstallContext context;
public void install(Provider provider) {
holder.set(provider);
int count = counter.incrementAndGet();
if (count == 1) {
context = new InstallContext(provider);
Configuration.setConfiguration(this);
LogFactory.getLog(LoginConfiguration.class).trace("installed login configuration", context.stacktrace);
}
}
public void uninstall() {
holder.remove();
int count = counter.decrementAndGet();
if (count == 0) {
LogFactory.getLog(LoginConfiguration.class).trace("uninstalled login configuration " + context.thread,
context.stacktrace);
Configuration.setConfiguration(context.parent);
context = null;
}
}
/**
* @since 5.9.5
*/
public void cleanupThisThread() {
holder.remove();
}
}