306 lines
9.7 KiB
Java
306 lines
9.7 KiB
Java
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The ASF licenses this file to You 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.apache.naming;
|
|
|
|
import java.util.Hashtable;
|
|
|
|
import javax.naming.Context;
|
|
import javax.naming.NamingException;
|
|
|
|
/**
|
|
* Handles the associations :
|
|
* <ul>
|
|
* <li>Object with a NamingContext</li>
|
|
* <li>Calling thread with a NamingContext</li>
|
|
* <li>Calling thread with object bound to the same naming context</li>
|
|
* <li>Thread context class loader with a NamingContext</li>
|
|
* <li>Thread context class loader with object bound to the same
|
|
* NamingContext</li>
|
|
* </ul>
|
|
* The objects are typically Catalina Server or Context objects.
|
|
*
|
|
* @author Remy Maucherat
|
|
*/
|
|
public class ContextBindings {
|
|
|
|
// -------------------------------------------------------------- Variables
|
|
|
|
/**
|
|
* Bindings object - naming context. Keyed by object.
|
|
*/
|
|
private static final Hashtable<Object,Context> objectBindings = new Hashtable<>();
|
|
|
|
|
|
/**
|
|
* Bindings thread - naming context. Keyed by thread.
|
|
*/
|
|
private static final Hashtable<Thread,Context> threadBindings = new Hashtable<>();
|
|
|
|
|
|
/**
|
|
* Bindings thread - object. Keyed by thread.
|
|
*/
|
|
private static final Hashtable<Thread,Object> threadObjectBindings = new Hashtable<>();
|
|
|
|
|
|
/**
|
|
* Bindings class loader - naming context. Keyed by class loader.
|
|
*/
|
|
private static final Hashtable<ClassLoader,Context> clBindings = new Hashtable<>();
|
|
|
|
|
|
/**
|
|
* Bindings class loader - object. Keyed by class loader.
|
|
*/
|
|
private static final Hashtable<ClassLoader,Object> clObjectBindings = new Hashtable<>();
|
|
|
|
|
|
/**
|
|
* The string manager for this package.
|
|
*/
|
|
protected static final StringManager sm = StringManager.getManager(ContextBindings.class);
|
|
|
|
|
|
// --------------------------------------------------------- Public Methods
|
|
|
|
/**
|
|
* Binds an object and a naming context.
|
|
*
|
|
* @param obj Object to bind with naming context
|
|
* @param context Associated naming context instance
|
|
*/
|
|
public static void bindContext(Object obj, Context context) {
|
|
bindContext(obj, context, null);
|
|
}
|
|
|
|
|
|
/**
|
|
* Binds an object and a naming context.
|
|
*
|
|
* @param obj Object to bind with naming context
|
|
* @param context Associated naming context instance
|
|
* @param token Security token
|
|
*/
|
|
public static void bindContext(Object obj, Context context, Object token) {
|
|
if (ContextAccessController.checkSecurityToken(obj, token)) {
|
|
objectBindings.put(obj, context);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Unbinds an object and a naming context.
|
|
*
|
|
* @param obj Object to unbind
|
|
* @param token Security token
|
|
*/
|
|
public static void unbindContext(Object obj, Object token) {
|
|
if (ContextAccessController.checkSecurityToken(obj, token)) {
|
|
objectBindings.remove(obj);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieve a naming context.
|
|
*
|
|
* @param obj Object bound to the required naming context
|
|
*/
|
|
static Context getContext(Object obj) {
|
|
return objectBindings.get(obj);
|
|
}
|
|
|
|
|
|
/**
|
|
* Binds a naming context to a thread.
|
|
*
|
|
* @param obj Object bound to the required naming context
|
|
* @param token Security token
|
|
*
|
|
* @throws NamingException If no naming context is bound to the provided
|
|
* object
|
|
*/
|
|
public static void bindThread(Object obj, Object token) throws NamingException {
|
|
if (ContextAccessController.checkSecurityToken(obj, token)) {
|
|
Context context = objectBindings.get(obj);
|
|
if (context == null) {
|
|
throw new NamingException(
|
|
sm.getString("contextBindings.unknownContext", obj));
|
|
}
|
|
threadBindings.put(Thread.currentThread(), context);
|
|
threadObjectBindings.put(Thread.currentThread(), obj);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Unbinds a thread and a naming context.
|
|
*
|
|
* @param obj Object bound to the required naming context
|
|
* @param token Security token
|
|
*/
|
|
public static void unbindThread(Object obj, Object token) {
|
|
if (ContextAccessController.checkSecurityToken(obj, token)) {
|
|
threadBindings.remove(Thread.currentThread());
|
|
threadObjectBindings.remove(Thread.currentThread());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieves the naming context bound to the current thread.
|
|
*
|
|
* @return The naming context bound to the current thread.
|
|
*
|
|
* @throws NamingException If no naming context is bound to the current
|
|
* thread
|
|
*/
|
|
public static Context getThread() throws NamingException {
|
|
Context context = threadBindings.get(Thread.currentThread());
|
|
if (context == null) {
|
|
throw new NamingException
|
|
(sm.getString("contextBindings.noContextBoundToThread"));
|
|
}
|
|
return context;
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieves the name of the object bound to the naming context that is also
|
|
* bound to the current thread.
|
|
*/
|
|
static String getThreadName() throws NamingException {
|
|
Object obj = threadObjectBindings.get(Thread.currentThread());
|
|
if (obj == null) {
|
|
throw new NamingException
|
|
(sm.getString("contextBindings.noContextBoundToThread"));
|
|
}
|
|
return obj.toString();
|
|
}
|
|
|
|
|
|
/**
|
|
* Tests if current thread is bound to a naming context.
|
|
*
|
|
* @return <code>true</code> if the current thread is bound to a naming
|
|
* context, otherwise <code>false</code>
|
|
*/
|
|
public static boolean isThreadBound() {
|
|
return threadBindings.containsKey(Thread.currentThread());
|
|
}
|
|
|
|
|
|
/**
|
|
* Binds a naming context to a class loader.
|
|
*
|
|
* @param obj Object bound to the required naming context
|
|
* @param token Security token
|
|
* @param classLoader The class loader to bind to the naming context
|
|
*
|
|
* @throws NamingException If no naming context is bound to the provided
|
|
* object
|
|
*/
|
|
public static void bindClassLoader(Object obj, Object token,
|
|
ClassLoader classLoader) throws NamingException {
|
|
if (ContextAccessController.checkSecurityToken(obj, token)) {
|
|
Context context = objectBindings.get(obj);
|
|
if (context == null) {
|
|
throw new NamingException
|
|
(sm.getString("contextBindings.unknownContext", obj));
|
|
}
|
|
clBindings.put(classLoader, context);
|
|
clObjectBindings.put(classLoader, obj);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Unbinds a naming context and a class loader.
|
|
*
|
|
* @param obj Object bound to the required naming context
|
|
* @param token Security token
|
|
* @param classLoader The class loader bound to the naming context
|
|
*/
|
|
public static void unbindClassLoader(Object obj, Object token,
|
|
ClassLoader classLoader) {
|
|
if (ContextAccessController.checkSecurityToken(obj, token)) {
|
|
Object o = clObjectBindings.get(classLoader);
|
|
if (o == null || !o.equals(obj)) {
|
|
return;
|
|
}
|
|
clBindings.remove(classLoader);
|
|
clObjectBindings.remove(classLoader);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieves the naming context bound to a class loader.
|
|
*
|
|
* @return the naming context bound to current class loader or one of its
|
|
* parents
|
|
*
|
|
* @throws NamingException If no naming context was bound
|
|
*/
|
|
public static Context getClassLoader() throws NamingException {
|
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
|
Context context = null;
|
|
do {
|
|
context = clBindings.get(cl);
|
|
if (context != null) {
|
|
return context;
|
|
}
|
|
} while ((cl = cl.getParent()) != null);
|
|
throw new NamingException(sm.getString("contextBindings.noContextBoundToCL"));
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieves the name of the object bound to the naming context that is also
|
|
* bound to the thread context class loader.
|
|
*/
|
|
static String getClassLoaderName() throws NamingException {
|
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
|
Object obj = null;
|
|
do {
|
|
obj = clObjectBindings.get(cl);
|
|
if (obj != null) {
|
|
return obj.toString();
|
|
}
|
|
} while ((cl = cl.getParent()) != null);
|
|
throw new NamingException (sm.getString("contextBindings.noContextBoundToCL"));
|
|
}
|
|
|
|
|
|
/**
|
|
* Tests if the thread context class loader is bound to a context.
|
|
*
|
|
* @return <code>true</code> if the thread context class loader or one of
|
|
* its parents is bound to a naming context, otherwise
|
|
* <code>false</code>
|
|
*/
|
|
public static boolean isClassLoaderBound() {
|
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
|
do {
|
|
if (clBindings.containsKey(cl)) {
|
|
return true;
|
|
}
|
|
} while ((cl = cl.getParent()) != null);
|
|
return false;
|
|
}
|
|
}
|