Package org.jboss.as.naming

Source Code of org.jboss.as.naming.WritableServiceBasedNamingStore

/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, 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.as.naming;

import org.jboss.as.naming.deployment.JndiNamingDependencyProcessor;
import org.jboss.as.naming.deployment.RuntimeBindReleaseService;
import org.jboss.as.naming.logging.NamingLogger;
import org.jboss.as.naming.service.BinderService;
import org.jboss.as.naming.service.SharedBinderService;
import org.jboss.as.naming.util.ThreadLocalStack;
import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceRegistry;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.msc.service.StabilityMonitor;
import org.jboss.msc.value.ImmediateValue;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import java.util.Hashtable;

import static org.jboss.as.naming.util.NamingUtils.isLastComponentEmpty;
import static org.jboss.as.naming.util.NamingUtils.namingException;

/**
* @author John Bailey
* @author Eduardo Martins
* @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
*/
public class WritableServiceBasedNamingStore extends ServiceBasedNamingStore implements WritableNamingStore {
    private static final ThreadLocalStack WRITE_OWNER = new ThreadLocalStack();

    private final ServiceTarget serviceTarget;

    public WritableServiceBasedNamingStore(ServiceRegistry serviceRegistry, ServiceName serviceNameBase, ServiceTarget serviceTarget) {
        super(serviceRegistry, serviceNameBase);
        this.serviceTarget = serviceTarget;
    }

    public void bind(final Name name, final Object object, final Class<?> bindType) throws NamingException {
        bind(name, object);
    }

    public void bind(final Name name, final Object object) throws NamingException {
        final Object owner = requireOwner();
        final ServiceName bindName = buildServiceName(name);
        bind(name, object, owner, bindName);
    }

    private void bind(Name name, Object object, Object owner, ServiceName bindName) throws NamingException {
        ServiceTarget serviceTarget = this.serviceTarget;
        ServiceName deploymentUnitServiceName = null;
        if (owner instanceof ServiceName) {
            deploymentUnitServiceName = (ServiceName) owner;
        } else {
            serviceTarget = (ServiceTarget) owner;
        }
        try {
            // unlike on deployment processors, we may assume here it's a shareable bind if the owner is a deployment, because deployment unshareable namespaces are readonly stores
            final BinderService binderService = deploymentUnitServiceName != null ? new SharedBinderService(name.toString(), null) : new BinderService(name.toString(), null);
            final ServiceBuilder<?> builder = serviceTarget.addService(bindName, binderService)
                    .addDependency(getServiceNameBase(), ServiceBasedNamingStore.class, binderService.getNamingStoreInjector())
                    .addInjection(binderService.getManagedObjectInjector(), new ImmediateManagedReferenceFactory(object))
                    .setInitialMode(ServiceController.Mode.ACTIVE);
            final ServiceController<?> binderServiceController = builder.install();
            final StabilityMonitor monitor = new StabilityMonitor();
            monitor.addController(binderServiceController);
            try {
                monitor.awaitStability();
            } finally {
                monitor.removeController(binderServiceController);
            }
            final Exception startException = binderServiceController.getStartException();
            if (startException != null) {
                throw startException;
            }
            if (deploymentUnitServiceName != null) {
                final RuntimeBindReleaseService.References duBindingReferences = (RuntimeBindReleaseService.References) binderServiceController.getServiceContainer().getService(JndiNamingDependencyProcessor.serviceName(deploymentUnitServiceName)).getValue();
                duBindingReferences.acquire(((SharedBinderService) binderService));
            }
        } catch (Exception e) {
            throw namingException("Failed to bind [" + object + "] at location [" + bindName + "]", e);
        }
    }

    public void rebind(Name name, Object object) throws NamingException {
        final Object owner = requireOwner();
        // re-set the existent binder service injected value
        final ServiceName bindName = buildServiceName(name);
        final ServiceController<?> controller = getServiceRegistry().getService(bindName);
        if (controller == null) {
            bind(name, object, owner, bindName);
        } else {
            final BinderService binderService = (BinderService) controller.getService();
            if (owner instanceof ServiceName && binderService instanceof SharedBinderService) {
                final ServiceName deploymentUnitServiceName = (ServiceName) owner;
                final RuntimeBindReleaseService.References duBindingReferences = (RuntimeBindReleaseService.References) controller.getServiceContainer().getService(JndiNamingDependencyProcessor.serviceName(deploymentUnitServiceName)).getValue();
                duBindingReferences.acquire(((SharedBinderService) binderService));
            }
            binderService.getManagedObjectInjector().setValue(new ImmediateValue(new ImmediateManagedReferenceFactory(object)));
        }
    }

    public void rebind(final Name name, final Object object, final Class<?> bindType) throws NamingException {
        rebind(name, object);
    }

    public void unbind(final Name name) throws NamingException {
        requireOwner();
        final ServiceName bindName = buildServiceName(name);
        final ServiceController<?> controller = getServiceRegistry().getService(bindName);
        if (controller == null) {
            throw NamingLogger.ROOT_LOGGER.cannotResolveService(bindName);
        }
        ((BinderService) controller.getService()).stopNow();
        final StabilityMonitor monitor = new StabilityMonitor();
        monitor.addController(controller);
        try {
            monitor.awaitStability();
        } catch (Exception e) {
            throw namingException("Failed to unbind [" + bindName + "]", e);
        } finally {
            monitor.removeController(controller);
        }
    }

    public Context createSubcontext(final Name name) throws NamingException {
        requireOwner();
        if (isLastComponentEmpty(name)) {
            throw NamingLogger.ROOT_LOGGER.emptyNameNotAllowed();
        }
        return new NamingContext(name, WritableServiceBasedNamingStore.this, new Hashtable<String, Object>());
    }

    private Object requireOwner() {
        final Object owner = WRITE_OWNER.peek();
        if (owner == null) {
            throw NamingLogger.ROOT_LOGGER.readOnlyNamingContext();
        }
        return owner;
    }

    public static void pushOwner(final ServiceName deploymentUnitServiceName) {
        WRITE_OWNER.push(deploymentUnitServiceName);
    }

    public static void pushOwner(final ServiceTarget serviceTarget) {
        WRITE_OWNER.push(serviceTarget);
    }

    public static void popOwner() {
        WRITE_OWNER.pop();
    }

}
TOP

Related Classes of org.jboss.as.naming.WritableServiceBasedNamingStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.