/* * JBoss, Home of Professional Open Source. * Copyright 2015, Red Hat Middleware LLC, 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.wsf.stack.cxf.client.configuration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap; import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; import org.apache.cxf.bus.CXFBusFactory; import org.apache.cxf.bus.extension.ExtensionManagerBus; import org.apache.cxf.buslifecycle.BusLifeCycleListener; import org.apache.cxf.buslifecycle.BusLifeCycleManager; import org.apache.cxf.configuration.Configurer; import org.apache.cxf.resource.ResourceManager; import org.jboss.wsf.stack.cxf.client.ClientBusSelector; import org.jboss.wsf.stack.cxf.client.ProviderImpl; import org.jboss.wsf.stack.cxf.client.injection.JBossWSResourceInjectionResolver; /** * JBossWS version of @see{org.apache.cxf.BusFactory}. * * @author alessio.soldano@jboss.com * @since 16-Jun-2010 * */ public class JBossWSBusFactory extends CXFBusFactory { private static final Map<ClassLoader, Bus> classLoaderBusses = new WeakHashMap<ClassLoader, Bus>(); @Override public Bus createBus(Map<Class<?>, Object> extensions, Map<String, Object> properties) { if (extensions == null) { extensions = new HashMap<Class<?>, Object>(); } if (!extensions.containsKey(Configurer.class)) { extensions.put(Configurer.class, new JBossWSConfigurerImpl(new BeanCustomizer())); } //Explicitly ask for the ProviderImpl.class.getClassLoader() to be used for getting //cxf bus extensions (as that classloader is the jaxws-client module one which 'sees' all //extensions, unless different dependencies are explicitly set) ExtensionManagerBus bus = new ExtensionManagerBus(extensions, properties, ProviderImpl.class.getClassLoader()); possiblySetDefaultBus(bus); initializeBus(bus); bus.initialize(); DefaultHTTPConduitFactoryWrapper.install(bus); return bus; } protected void initializeBus(Bus bus) { super.initializeBus(bus); final ResourceManager resourceManager = bus.getExtension(ResourceManager.class); resourceManager.addResourceResolver(JBossWSResourceInjectionResolver.getInstance()); SecurityProviderConfig.setup(bus); } /** * Gets (and internally sets) the default bus after having set the thread * context class loader to the provided one (which affects the Bus * construction if it's not been created yet). The former thread context * class loader is restored before returning to the caller. * * @param contextClassLoader * @return the default bus */ public static Bus getDefaultBus(ClassLoader contextClassLoader) { ClassLoader origClassLoader = SecurityActions.getContextClassLoader(); try { SecurityActions.setContextClassLoader(contextClassLoader); return BusFactory.getDefaultBus(); } finally { SecurityActions.setContextClassLoader(origClassLoader); } } /** * Gets the default bus for the given classloader; if a new Bus is needed, * the creation is delegated to the specified ClientBusSelector instance. * * @param classloader * @param clientBusSelector * @return */ public static Bus getClassLoaderDefaultBus(final ClassLoader classloader, final ClientBusSelector clientBusSelector) { Bus classLoaderBus; synchronized (classLoaderBusses) { classLoaderBus = classLoaderBusses.get(classloader); if (classLoaderBus == null) { classLoaderBus = clientBusSelector.createNewBus(); //register a listener for cleaning up the bus from the classloader association in the JBossWSBusFactory BusLifeCycleListener listener = new ClassLoaderDefaultBusLifeCycleListener(classLoaderBus); classLoaderBus.getExtension(BusLifeCycleManager.class).registerLifeCycleListener(listener); classLoaderBusses.put(classloader, classLoaderBus); } } return classLoaderBus; } /** * Gets the default bus for the given classloader * * @param classloader * @return */ public static Bus getClassLoaderDefaultBus(final ClassLoader classloader) { Bus classLoaderBus; synchronized (classLoaderBusses) { classLoaderBus = classLoaderBusses.get(classloader); if (classLoaderBus == null) { classLoaderBus = new JBossWSBusFactory().createBus(); //register a listener for cleaning up the bus from the classloader association in the JBossWSBusFactory BusLifeCycleListener listener = new ClassLoaderDefaultBusLifeCycleListener(classLoaderBus); classLoaderBus.getExtension(BusLifeCycleManager.class).registerLifeCycleListener(listener); classLoaderBusses.put(classloader, classLoaderBus); } } return classLoaderBus; } /** * Removes a bus from being the default bus for any classloader * * @param bus */ public static void clearDefaultBusForAnyClassLoader(final Bus bus) { synchronized (classLoaderBusses) { for (final Iterator<Bus> iterator = classLoaderBusses.values().iterator(); iterator.hasNext();) { Bus itBus = iterator.next(); if (bus == null || itBus == null|| bus.equals(itBus)) { iterator.remove(); } } } } private static class ClassLoaderDefaultBusLifeCycleListener implements BusLifeCycleListener { private final Bus bus; public ClassLoaderDefaultBusLifeCycleListener(final Bus bus) { this.bus = bus; } @Override public void initComplete() { // NOOP } @Override public void preShutdown() { // NOOP } @Override public void postShutdown() { JBossWSBusFactory.clearDefaultBusForAnyClassLoader(this.bus); } } }