Author: bimargulies Date: Sat Nov 20 23:30:59 2010 New Revision: 1037355 URL: http://svn.apache.org/viewvc?rev=1037355&view=rev Log: Add javadoc to the BusFactory, particularly to reflect CXF-3142.
Modified: cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java Modified: cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java?rev=1037355&r1=1037354&r2=1037355&view=diff ============================================================================== --- cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java (original) +++ cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java Sat Nov 20 23:30:59 2010 @@ -32,8 +32,42 @@ import java.util.logging.Logger; import org.apache.cxf.common.classloader.ClassLoaderUtils; import org.apache.cxf.common.logging.LogUtils; +/** + * Factory to create CXF Bus objects. + * <p>CXF includes a large number of components that provide services, such + * as WSDL parsing, and message processing. To avoid creating these objects over and over, and to + * allow them to be shared easily, they are associated with a data structure called a bus. + * </p> + * <p> + * You don't ever have to explicitly create or manipulate bus objects. If you simply use the CXF + * or JAX-WS APIs to create clients or servers, CXF will create an default bus for you. You would create a bus + * explicitly if you need to customize components on the bus or maintain several independent buses + * with independent configurations. + * </p> + * <p> + * This class maintains the default bus for the entire process and a set of thread-default buses. All CXF + * components that reference the bus, which is to say all CXF components, will obtain a default bus from this + * class if you do not set a specific bus. + * </p> + * <p> + * If you create a bus when there is no default bus in effect, that bus will become the default bus. + * </p> + * <p> + * This class holds <strong>weak</strong> references to the global default bus and the per-thread default + * busses. Thus, if you create and customize a bus, you must retain a reference to it if you want it to be + * protected from garbage collection. If you do not, you might experience the following unexpected chain of + * events, especially in a client: + * <ol> + * <li>Create a bus and customize it. Fail to hold a reference.</li> + * <li>Release all references to CXF objects.</li> + * <li>GC collects the Bus.</li> + * <li>Create a new CXF object.</li> + * <li>Implicitly create a new, default, bus.</li> + * </ol> + * </p> + */ public abstract class BusFactory { - + public static final String BUS_FACTORY_PROPERTY_NAME = "org.apache.cxf.bus.factory"; public static final String DEFAULT_BUS_FACTORY = "org.apache.cxf.bus.CXFBusFactory"; @@ -41,18 +75,15 @@ public abstract class BusFactory { protected static Map<Thread, Bus> threadBusses = new WeakHashMap<Thread, Bus>(); private static final Logger LOG = LogUtils.getL7dLogger(BusFactory.class, "APIMessages"); - - /** - * Creates a new bus. - * While concrete <code>BusFactory</code> may offer differently - * parameterized methods for creating a bus, all factories support - * this no-arg factory method. - * + /** + * Creates a new bus. While concrete <code>BusFactory</code> may offer differently parameterized methods + * for creating a bus, all factories support this no-arg factory method. + * * @return the newly created bus. */ public abstract Bus createBus(); - + /** * Returns the default bus, creating it if necessary. * @@ -61,15 +92,15 @@ public abstract class BusFactory { public static synchronized Bus getDefaultBus() { return getDefaultBus(true); } - + /** * Returns the default bus + * * @param createIfNeeded Set to true to create a default bus if one doesn't exist * @return the default bus. */ public static synchronized Bus getDefaultBus(boolean createIfNeeded) { - if ((defaultBus == null || defaultBus.get() == null) - && createIfNeeded) { + if ((defaultBus == null || defaultBus.get() == null) && createIfNeeded) { defaultBus = new WeakReference<Bus>(newInstance().createBus()); } if (defaultBus == null) { @@ -79,9 +110,10 @@ public abstract class BusFactory { return defaultBus.get(); } } - + /** * Sets the default bus. + * * @param bus the default bus. */ public static synchronized void setDefaultBus(Bus bus) { @@ -92,10 +124,10 @@ public abstract class BusFactory { } setThreadDefaultBus(bus); } - - + /** * Sets the default bus for the thread. + * * @param bus the default bus. */ public static void setThreadDefaultBus(Bus bus) { @@ -103,16 +135,19 @@ public abstract class BusFactory { threadBusses.put(Thread.currentThread(), bus); } } - + /** * Gets the default bus for the thread. + * * @return the default bus. */ public static Bus getThreadDefaultBus() { return getThreadDefaultBus(true); } + /** * Gets the default bus for the thread, creating if needed + * * @param createIfNeeded Set to true to create a default bus if one doesn't exist * @return the default bus. */ @@ -135,17 +170,15 @@ public abstract class BusFactory { /** * Removes a bus from being a thread default bus for any thread. * <p> - * This is tipically done when a bus has ended its lifecycle (i.e.: a call - * to {...@link Bus#shutdown(boolean)} was invoked) and it wants to remove any - * reference to itself for any thread. + * This is tipically done when a bus has ended its lifecycle (i.e.: a call to + * {...@link Bus#shutdown(boolean)} was invoked) and it wants to remove any reference to itself for any + * thread. * - * @param bus - * the bus to remove + * @param bus the bus to remove */ public static void clearDefaultBusForAnyThread(final Bus bus) { synchronized (threadBusses) { - for (final Iterator<Bus> iterator = threadBusses.values().iterator(); - iterator.hasNext();) { + for (final Iterator<Bus> iterator = threadBusses.values().iterator(); iterator.hasNext();) { if (bus == null || bus.equals(iterator.next())) { iterator.remove(); } @@ -155,6 +188,7 @@ public abstract class BusFactory { /** * Sets the default bus if a default bus is not already set. + * * @param bus the default bus. * @return true if the bus was not set and is now set */ @@ -164,21 +198,18 @@ public abstract class BusFactory { threadBusses.put(Thread.currentThread(), bus); } } - // The default bus may have gc-ed itself out of existence, in which case we + // The default bus may have gc-ed itself out of existence, in which case we // take over for it. if (defaultBus == null || defaultBus.get() == null) { - defaultBus = new WeakReference<Bus>(bus); + defaultBus = new WeakReference<Bus>(bus); return true; - } + } return false; } /** - * Create a new BusFactory - * - * The class of the BusFactory is determined by looking for the system propery: - * org.apache.cxf.bus.factory - * or by searching the classpath for: + * Create a new BusFactory The class of the BusFactory is determined by looking for the system propery: + * org.apache.cxf.bus.factory or by searching the classpath for: * META-INF/services/org.apache.cxf.bus.factory * * @return a new BusFactory to be used to create Bus objects @@ -186,11 +217,11 @@ public abstract class BusFactory { public static BusFactory newInstance() { return newInstance(null); } - + /** * Create a new BusFactory - * @param className The class of the BusFactory to create. If null, uses the - * default search algorithm. + * + * @param className The class of the BusFactory to create. If null, uses the default search algorithm. * @return a new BusFactory to be used to create Bus objects */ public static BusFactory newInstance(String className) { @@ -199,17 +230,17 @@ public abstract class BusFactory { ClassLoader loader = Thread.currentThread().getContextClassLoader(); className = getBusFactoryClass(loader); if (className == null && loader != BusFactory.class.getClassLoader()) { - className = getBusFactoryClass(BusFactory.class.getClassLoader()); + className = getBusFactoryClass(BusFactory.class.getClassLoader()); } } if (className == null) { className = BusFactory.DEFAULT_BUS_FACTORY; } - + Class<? extends BusFactory> busFactoryClass; try { - busFactoryClass = - ClassLoaderUtils.loadClass(className, BusFactory.class).asSubclass(BusFactory.class); + busFactoryClass = ClassLoaderUtils.loadClass(className, BusFactory.class) + .asSubclass(BusFactory.class); instance = busFactoryClass.newInstance(); } catch (Exception ex) { LogUtils.log(LOG, Level.SEVERE, "BUS_FACTORY_INSTANTIATION_EXC", ex); @@ -220,47 +251,46 @@ public abstract class BusFactory { protected void initializeBus(Bus bus) { } - + private static String getBusFactoryClass(ClassLoader classLoader) { - + String busFactoryClass = null; String busFactoryCondition = null; - + // next check system properties busFactoryClass = System.getProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME); if (isValidBusFactoryClass(busFactoryClass)) { return busFactoryClass; } - + try { // next, check for the services stuff in the jar file String serviceId = "META-INF/services/" + BusFactory.BUS_FACTORY_PROPERTY_NAME; InputStream is = null; - + if (classLoader == null) { classLoader = Thread.currentThread().getContextClassLoader(); } - + if (classLoader == null) { is = ClassLoader.getSystemResourceAsStream(serviceId); } else { - is = classLoader.getResourceAsStream(serviceId); + is = classLoader.getResourceAsStream(serviceId); } if (is == null) { serviceId = "META-INF/cxf/" + BusFactory.BUS_FACTORY_PROPERTY_NAME; - + if (classLoader == null) { classLoader = Thread.currentThread().getContextClassLoader(); } - + if (classLoader == null) { is = ClassLoader.getSystemResourceAsStream(serviceId); } else { - is = classLoader.getResourceAsStream(serviceId); + is = classLoader.getResourceAsStream(serviceId); } } - - + if (is != null) { BufferedReader rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); busFactoryClass = rd.readLine(); @@ -269,7 +299,7 @@ public abstract class BusFactory { } if (isValidBusFactoryClass(busFactoryClass)) { if (busFactoryCondition != null) { - try { + try { classLoader.loadClass(busFactoryCondition); return busFactoryClass; } catch (ClassNotFoundException e) { @@ -283,13 +313,12 @@ public abstract class BusFactory { } catch (Exception ex) { LogUtils.log(LOG, Level.SEVERE, "FAILED_TO_DETERMINE_BUS_FACTORY_EXC", ex); - } + } return busFactoryClass; } - - private static boolean isValidBusFactoryClass(String busFactoryClassName) { + + private static boolean isValidBusFactoryClass(String busFactoryClassName) { return busFactoryClassName != null && !"".equals(busFactoryClassName); } - + } - \ No newline at end of file