/**
*
* Copyright 2004-2005 The Apache Software Foundation
*
* 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.apache.geronimo.interop.naming;
import java.util.HashMap;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.Context;
import org.apache.geronimo.interop.adapter.Adapter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class NamingContext {
private final Log log = LogFactory.getLog(NamingContext.class);
public static final NamingContext getInstance(Class baseClass) {
NamingContext context;
synchronized (contextMap) {
context = (NamingContext) contextMap.get(baseClass);
if (context == null) {
context = new NamingContext();
contextMap.put(baseClass, context);
context.init(baseClass);
}
}
return context;
}
private static ThreadLocal current = new ThreadLocal();
private static HashMap contextMap = new HashMap();
private static boolean quiet = false; // TODO: Configure
private static boolean verbose = true; // TODO: Configure
private String logContext;
private HashMap map = new HashMap();
private HashMap failedBindings = new HashMap();
public static final NamingContext getCurrent() {
return (NamingContext) current.get();
}
public static final NamingContext push(NamingContext that) {
NamingContext restore = getCurrent();
current.set(that);
return restore;
}
public static void pop(NamingContext restore) {
current.set(restore);
}
public HashMap getMap() {
return map;
}
public Object lookup(String name, String prefix) throws NamingException {
log.debug( "NameContext.lookup(): name = " + name + ", prefix = " + prefix );
if (prefix != null) {
name += prefix + "/" + name;
}
// Note: this part of the method is performance critical. Please
// refrain from using string concatenation, synchronization and
// other slow calls here. All possible initialization should
// be performed in 'init' so as to permit this method to be as
// fast as possible (i.e. a simple unsynchronized HashMap lookup).
Object value = map.get(name);
if (value == null) {
value = dynamicLookup(name);
if (value != null) {
map.put(name, value); // TODO: allow refresh.
}
}
// If it is corbaname type bind, give it one more chance to bind
// if not already bound.
if (value == null)
{
value = tryBindCorbaName(name);
}
if (value == null) {
NameNotFoundException notFound = new NameNotFoundException(name.length() == 0 ? formatEmptyName() : name);
if (!quiet) {
NameServiceLog.getInstance().warnNameNotFound(logContext, notFound);
}
throw notFound;
} else {
return value;
}
}
public Object lookupReturnNullIfNotFound(String name, String prefix) {
if (prefix != null) {
name += prefix + "/" + name;
}
return map.get(name);
}
protected void init(Class baseClass) {
// TODO: Nothing really to do as this would init all the env-prop res-ref ... from a component
// this logic isn't required for the CORBA container.
}
protected synchronized void bindAdapter(Adapter adp) {
String names[] = adp.getBindNames();
for( int i=0; i<names.length; i++ ) {
log.debug( "NameContext.bindAdapter(): name[" + i + "] = " + names[i] + ", adp = " + adp );
map.put(names[i], adp);
}
}
protected synchronized void unbindAdapter( Adapter adp ) {
String names[] = adp.getBindNames();
for( int i=0; i<names.length; i++ )
{
log.debug( "NameContext.bindAdapter(): name[" + i + "] = " + names[i] + ", adp = " + adp );
map.remove( names[i] );
}
}
protected boolean adapterExists(String name) {
System.out.println("TODO: NamingComponent.componentExists(): name = " + name);
return false;
}
/*
* The allows the server to bind an object whose name beings with "lookup=".
* The lookup= instructs the name service to perform a lookup on another name
* service.
*/
protected Object bindCorbaName(String name, String value)
{
String url = value.substring("lookup=".length());
/*
* value will only have the following two patterns:
*
* lookup=corbaname...
* lookup=corbaloc...
*
* These are placed into the URL that is sent to the context factory.
* The context factory then determine how to perform a lookup on a
* given corbaname or corbaloc url.
*/
java.util.Properties p = new java.util.Properties();
/*
* corbaname and corbaloc urls are not supported by the OpenEJB name service
*/
p.put(Context.INITIAL_CONTEXT_FACTORY, "" ); // org.openejb.client.RemoteInitialContextFactory ??
p.put(Context.PROVIDER_URL, url);
Context initialContext = null;
Object object = null;
try
{
initialContext = new javax.naming.InitialContext(p);
object = initialContext.lookup("");
}
catch (javax.naming.NamingException ne)
{
failedBindings(name, value);
NameServiceLog.getInstance().warnBindFailed(logContext, name, url, ne);
return null;
}
catch (java.lang.IllegalArgumentException ie)
{
NameServiceLog.getInstance().warnBindFailed(logContext, name, url, ie);
return null;
}
catch (Exception ex)
{
failedBindings(name, value);
NameServiceLog.getInstance().warnBindFailed(logContext, name, url, ex);
return null;
}
if (object == null)
{
NameServiceLog.getInstance().warnIllegalBindValue(logContext, Object.class, name, url);
return null;
}
map.put(name, object);
return object;
}
protected Object dynamicLookup(String name) {
return null;
}
protected String formatEmptyName() {
return "formatEmptyName:";
}
// bind for corbaname failed at server startup. We will try to bind once
// again.
private Object tryBindCorbaName(String name)
{
Object obj = null;
Object val = failedBindings.get(name);
if( val != null)
{
obj = bindCorbaName(name, (String)val);
}
return obj;
}
/**
* If corbaname bindings fail, give it one more chance at the time of
* lookup
*/
private void failedBindings(String name, String value)
{
Object val = failedBindings.get(name);
if( val == null)
{
failedBindings.put(name, value);
}
else
{
//If the binding already exists in the map, then we have already given
//it one more chance to bind. Time to remove it.
failedBindings.remove(name);
}
}
}