/* * JBoss, Home of Professional Open Source * Copyright 2008-12, Red Hat Middleware LLC, and others contributors as indicated * by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * 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, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.riftsaw.engine.jboss; import javax.naming.NamingException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.as.naming.ServiceBasedNamingStore; import org.jboss.as.naming.ValueManagedReferenceFactory; import org.jboss.as.naming.deployment.ContextNames; import org.jboss.as.naming.service.BinderService; import org.jboss.as.server.CurrentServiceContainer; import org.jboss.msc.service.AbstractServiceListener; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceContainer; import org.jboss.msc.service.ServiceController; import org.jboss.msc.value.ImmediateValue; /** * @author: Jeff Yu * @date: 1/02/12 */ public class JndiRegistry { private static final Log LOG= LogFactory.getLog(JndiRegistry.class); public void bindToJndi(String name, Object object) { ServiceContainer serviceContainer = CurrentServiceContainer.getServiceContainer(); //Only register it in AS7 container. if (serviceContainer != null) { try { // creates binder service final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(name); final BinderService binderService = new BinderService(bindInfo.getBindName()); final BindListener listener = new BindListener(); binderService.getManagedObjectInjector().inject(new ValueManagedReferenceFactory(new ImmediateValue<Object>(object))); // creates the service builder with dep to the parent jndi context ServiceBuilder<?> builder = serviceContainer.addService(bindInfo.getBinderServiceName(), binderService) .addDependency(bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, binderService.getNamingStoreInjector()) .setInitialMode(ServiceController.Mode.ACTIVE) .addListener(listener); builder.install(); listener.await(); binderService.acquire(); }catch (Throwable e) { final NamingException ne = new NamingException("Failed to bind "+ object + " at location " + name); ne.setRootCause(e); LOG.error(ne); } } } public void unbindFromJndi(String name){ ServiceContainer serviceContainer = CurrentServiceContainer.getServiceContainer(); if (serviceContainer != null) { final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(name); final ServiceController<?> controller = serviceContainer.getService(bindInfo.getBinderServiceName()); final UnbindListener listener = new UnbindListener(); controller.addListener(listener); try { // when added, the listener stops the binding service listener.await(); } catch (Exception e) { LOG.error("Failed to unbind [" + name + "]", e); } } } private static class BindListener extends AbstractServiceListener<Object> { private Exception exception; private boolean complete; public synchronized void transition(ServiceController<? extends Object> serviceController, ServiceController.Transition transition) { switch (transition) { case STARTING_to_UP: { complete = true; notifyAll(); break; } case STARTING_to_START_FAILED: { complete = true; exception = serviceController.getStartException(); notifyAll(); break; } default: break; } } public synchronized void await() throws Exception { while(!complete) { wait(); } if (exception != null) { throw exception; } } } private static class UnbindListener extends AbstractServiceListener<Object> { private boolean complete; public void listenerAdded(ServiceController<?> controller) { controller.setMode(ServiceController.Mode.REMOVE); } public synchronized void transition(ServiceController<? extends Object> serviceController, ServiceController.Transition transition) { switch (transition) { case REMOVING_to_REMOVED: { complete = true; notifyAll(); break; } default: break; } } public synchronized void await() throws Exception { while(!complete) { wait(); } } } }