/* * RHQ Management Platform * Copyright (C) 2005-2011 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.naming.context; import java.io.Serializable; import java.util.Hashtable; import javax.naming.Binding; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.Name; import javax.naming.NameClassPair; import javax.naming.NameParser; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import org.rhq.enterprise.server.naming.AccessCheckingInitialContextFactoryBuilder; /** * This is a wrapper class around another {@link Context} implementation that * prefers to use an URL context for some operation if the JNDI name contains * a scheme rather than the original. This is the behavior of {@link InitialContext} * which we need to restore in the contexts created by the {@link AccessCheckingInitialContextFactoryBuilder} * (which an {@link InitialContext} uses exclusively if the builder is set). * <p> * This is important because RHQ server has its own initial context factory * builder that creates factories that in turn create contexts. If the default * {@link InitialContext} implementation was used, we'd never be able to lookup * scheme-based names because the default implementation of the {@link InitialContext} * always uses the default context of the builder if one is installed no matter * the scheme in the name. * <p> * The {@link AccessCheckingInitialContextFactoryBuilder} wraps the context returned * by the factory in an instance of this class and thus is restoring the original * intended behavior of the {@link InitialContext}. It looks at the name being looked * up (bound or whatever) and prefers to use the URL context factories if the name * contains the scheme (as does the {@link InitialContext} if no builder is installed). * If the name doesn't contain a scheme, the provided default context factory is used to * look up the name. * * @author Lukas Krejci */ public class URLPreferringContextDecorator implements Context, ContextDecorator, Serializable { private static final long serialVersionUID = 1L; private Context original; public URLPreferringContextDecorator() { } public URLPreferringContextDecorator(Context ctx) { original = ctx; } public void init(Context context) { original = context; } protected Context getOriginal() throws NamingException { return original; } protected Context getURLOrDefaultInitCtx(Name name) throws NamingException { @SuppressWarnings("unchecked") Context urlContext = URLPreferringContextDecoratorHelper.getURLContext(name, (Hashtable<Object, Object>) getEnvironment()); return urlContext == null ? getOriginal() : urlContext; } protected Context getURLOrDefaultInitCtx(String name) throws NamingException { @SuppressWarnings("unchecked") Context urlContext = URLPreferringContextDecoratorHelper.getURLContext(name, (Hashtable<Object, Object>) getEnvironment()); return urlContext == null ? getOriginal() : urlContext; } public Object lookup(Name name) throws NamingException { return getURLOrDefaultInitCtx(name).lookup(name); } public Object lookup(String name) throws NamingException { return getURLOrDefaultInitCtx(name).lookup(name); } public void bind(Name name, Object obj) throws NamingException { getURLOrDefaultInitCtx(name).bind(name, obj); } public void bind(String name, Object obj) throws NamingException { getURLOrDefaultInitCtx(name).bind(name, obj); } public void rebind(Name name, Object obj) throws NamingException { getURLOrDefaultInitCtx(name).rebind(name, obj); } public void rebind(String name, Object obj) throws NamingException { getURLOrDefaultInitCtx(name).rebind(name, obj); } public void unbind(Name name) throws NamingException { getURLOrDefaultInitCtx(name).unbind(name); } public void unbind(String name) throws NamingException { getURLOrDefaultInitCtx(name).unbind(name); } public void rename(Name oldName, Name newName) throws NamingException { getURLOrDefaultInitCtx(oldName).rename(oldName, newName); } public void rename(String oldName, String newName) throws NamingException { getURLOrDefaultInitCtx(oldName).rename(oldName, newName); } public NamingEnumeration<NameClassPair> list(Name name) throws NamingException { return getURLOrDefaultInitCtx(name).list(name); } public NamingEnumeration<NameClassPair> list(String name) throws NamingException { return getURLOrDefaultInitCtx(name).list(name); } public NamingEnumeration<Binding> listBindings(Name name) throws NamingException { return getURLOrDefaultInitCtx(name).listBindings(name); } public NamingEnumeration<Binding> listBindings(String name) throws NamingException { return getURLOrDefaultInitCtx(name).listBindings(name); } public void destroySubcontext(Name name) throws NamingException { getURLOrDefaultInitCtx(name).destroySubcontext(name); } public void destroySubcontext(String name) throws NamingException { getURLOrDefaultInitCtx(name).destroySubcontext(name); } public Context createSubcontext(Name name) throws NamingException { return getURLOrDefaultInitCtx(name).createSubcontext(name); } public Context createSubcontext(String name) throws NamingException { return getURLOrDefaultInitCtx(name).createSubcontext(name); } public Object lookupLink(Name name) throws NamingException { return getURLOrDefaultInitCtx(name).lookupLink(name); } public Object lookupLink(String name) throws NamingException { return getURLOrDefaultInitCtx(name).lookupLink(name); } public NameParser getNameParser(Name name) throws NamingException { return getURLOrDefaultInitCtx(name).getNameParser(name); } public NameParser getNameParser(String name) throws NamingException { return getURLOrDefaultInitCtx(name).getNameParser(name); } public Name composeName(Name name, Name prefix) throws NamingException { return getOriginal().composeName(name, prefix); } public String composeName(String name, String prefix) throws NamingException { return getOriginal().composeName(name, prefix); } public Object addToEnvironment(String propName, Object propVal) throws NamingException { return getOriginal().addToEnvironment(propName, propVal); } public Object removeFromEnvironment(String propName) throws NamingException { return getOriginal().removeFromEnvironment(propName); } public Hashtable<?, ?> getEnvironment() throws NamingException { return getOriginal().getEnvironment(); } public void close() throws NamingException { if (getOriginal() != null) { getOriginal().close(); original = null; } } public String getNameInNamespace() throws NamingException { return getOriginal().getNameInNamespace(); } @Override public int hashCode() { return original == null ? super.hashCode() : original.hashCode(); } @Override public boolean equals(Object o) { return original == null ? super.equals(o) : original.equals(o); } }