org.jboss.naming.remote.client.RemoteContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jboss-remote-naming Show documentation
Show all versions of jboss-remote-naming Show documentation
Library for remote naming (JNDI) with JBoss AS
/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.naming.remote.client;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import javax.naming.Binding;
import javax.naming.CompositeName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.LinkRef;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import org.jboss.logging.Logger;
import static org.jboss.naming.remote.client.ClientUtil.isEmpty;
import static org.jboss.naming.remote.client.ClientUtil.namingEnumeration;
import static org.jboss.naming.remote.client.ClientUtil.namingException;
/**
*
* @author John Bailey
*/
public class RemoteContext implements Context, NameParser {
private static final Logger log = Logger.getLogger(RemoteContext.class);
// Work around JVM's broken finalizer. All code touching these values has a purpose. Do not remove!
public static int STATIC_KEEP_ALIVE;
private static AtomicIntegerFieldUpdater keepAliveUpdater = AtomicIntegerFieldUpdater.newUpdater(RemoteContext.class, "keepAlive");
private volatile int keepAlive = STATIC_KEEP_ALIVE;
private final Name prefix;
private final Hashtable environment;
// All usage of namingStore must be surrounded with an update to keepAlive, to keep the context alive
private final RemoteNamingStore namingStore;
private final List closeTasks;
private final AtomicBoolean closed = new AtomicBoolean();
public RemoteContext(final RemoteNamingStore namingStore, final Hashtable environment) {
this(namingStore, environment, Collections.emptyList());
}
public RemoteContext(final RemoteNamingStore namingStore, final Hashtable environment, final List closeTasks) {
this(new CompositeName(), namingStore, environment, closeTasks);
}
public RemoteContext(final Name prefix, final RemoteNamingStore namingStore, final Hashtable environment) {
this(prefix, namingStore, environment, Collections.emptyList());
}
public RemoteContext(final Name prefix, final RemoteNamingStore namingStore, final Hashtable environment, final List closeTasks) {
this.prefix = prefix;
this.namingStore = namingStore;
this.environment = environment;
this.closeTasks = closeTasks;
}
public Object lookup(final Name name) throws NamingException {
try {
return lookupInternal(name);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
private Object lookupInternal(Name name) throws NamingException {
if (isEmpty(name)) {
return new RemoteContext(prefix, namingStore, environment);
}
final Name absoluteName = getAbsoluteName(name);
Object result = namingStore.lookup(absoluteName);
if (result instanceof LinkRef) {
result = resolveLink((LinkRef)result);
}
else if (result instanceof Reference) {
result = getObjectInstance((Reference)result, name, environment);
if (result instanceof LinkRef) {
result = resolveLink((LinkRef)result);
}
}
return result;
}
private Object getObjectInstance(final Reference reference, final Name name, final Hashtable, ?> environment) throws NamingException {
try {
final Class> factoryClass = Thread.currentThread().getContextClassLoader().loadClass(reference.getFactoryClassName());
ObjectFactory factory = ObjectFactory.class.cast(factoryClass.newInstance());
return factory.getObjectInstance(reference, name, this, environment);
} catch(NamingException e) {
throw e;
} catch(Throwable t) {
throw namingException("failed to get object instance from reference", t);
}
}
private Object resolveLink(LinkRef result) throws NamingException {
final Object linkResult;
try {
final LinkRef linkRef = (LinkRef) result;
final String referenceName = linkRef.getLinkName();
if (referenceName.startsWith("./")) {
linkResult = lookup(referenceName.substring(2));
} else {
linkResult = new InitialContext().lookup(referenceName);
}
} catch (Throwable t) {
throw namingException("failed to deref link",t);
}
return linkResult;
}
public Object lookup(final String name) throws NamingException {
return lookup(parse(name));
}
public void bind(final Name name, final Object object) throws NamingException {
try {
namingStore.bind(getAbsoluteName(name), object);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public void bind(final String name, final Object object) throws NamingException {
bind(parse(name), object);
}
public void rebind(final Name name, final Object object) throws NamingException {
try {
namingStore.rebind(name, object);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public void rebind(final String name, final Object object) throws NamingException {
rebind(parse(name), object);
}
public void unbind(final Name name) throws NamingException {
try {
namingStore.unbind(name);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public void unbind(final String name) throws NamingException {
unbind(parse(name));
}
public void rename(final Name name, final Name newName) throws NamingException {
try {
namingStore.rename(name, newName);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public void rename(final String name, final String newName) throws NamingException {
rename(parse(name), parse(newName));
}
public NamingEnumeration list(final Name name) throws NamingException {
try {
return namingEnumeration(namingStore.list(name));
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public NamingEnumeration list(final String name) throws NamingException {
return list(parse(name));
}
public NamingEnumeration listBindings(final Name name) throws NamingException {
try {
return namingEnumeration(namingStore.listBindings(name));
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public NamingEnumeration listBindings(final String name) throws NamingException {
return listBindings(parse(name));
}
public void destroySubcontext(final Name name) throws NamingException {
try {
namingStore.destroySubcontext(name);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public void destroySubcontext(final String name) throws NamingException {
destroySubcontext(parse(name));
}
public Context createSubcontext(final Name name) throws NamingException {
try {
return namingStore.createSubcontext(name);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public Context createSubcontext(final String name) throws NamingException {
return createSubcontext(parse(name));
}
public Object lookupLink(final Name name) throws NamingException {
try {
return namingStore.lookupLink(name);
} finally {
keepAliveUpdater.lazySet(this, keepAlive + 1);
}
}
public Object lookupLink(final String name) throws NamingException {
return lookupLink(parse(name));
}
public NameParser getNameParser(Name name) throws NamingException {
return this;
}
public NameParser getNameParser(String s) throws NamingException {
return this;
}
public Name composeName(Name name, Name prefix) throws NamingException {
final Name result = (Name) prefix.clone();
result.addAll(name);
return result;
}
public String composeName(String name, String prefix) throws NamingException {
return composeName(parse(name), parse(prefix)).toString();
}
public Object addToEnvironment(String s, Object o) throws NamingException {
return environment.put(s, o);
}
public Object removeFromEnvironment(String s) throws NamingException {
return environment.remove(s);
}
public Hashtable, ?> getEnvironment() throws NamingException {
return environment;
}
public void close() throws NamingException {
if(closed.compareAndSet(false, true)) {
for (CloseTask closeTask : closeTasks) {
closeTask.close(false);
}
}
}
public void finalize() {
if(closed.compareAndSet(false, true)) {
STATIC_KEEP_ALIVE = keepAlive;
for (CloseTask closeTask : closeTasks) {
closeTask.close(true);
}
}
}
public String getNameInNamespace() throws NamingException {
return prefix.toString();
}
public Name parse(final String name) throws NamingException {
return new CompositeName(name);
}
private Name getAbsoluteName(final Name name) throws NamingException {
if (name.isEmpty()) {
return composeName(name, prefix);
}
return composeName(name, prefix);
}
public static interface CloseTask {
void close(boolean isFinalize);
}
}