/*
 * JBoss, Home of Professional Open Source
 * Copyright 2010, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jboss.shrinkwrap.api;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.logging.Level;
import java.util.logging.Logger;

Mutable construction object for new instances of Configuration. Provides defaults for each property if not specified (null) according to the following:
  • executorService - Stay null, none is required and ShrinkWrap will create its own and destroy it when done as needed
  • extensionLoader - A new instance of the service extension loader from shrinkwrap-impl
Not thread-safe. When done altering properties here, a new configuration may be constructed by calling upon build().
Author:ALR, Ken Gullaksen
Version:$Revision: $
/** * Mutable construction object for new instances of {@link Configuration}. Provides defaults for each property if not * specified (null) according to the following: * * <ul> * <li><code>executorService</code> - Stay null, none is required and ShrinkWrap will create its own and destroy it when * done as needed</li> * <li><code>extensionLoader</code> - A new instance of the service extension loader from shrinkwrap-impl</li> * </ul> * * Not thread-safe. When done altering properties here, a new configuration may be constructed by calling upon * {@link ConfigurationBuilder#build()}. * * @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a> * @author <a href="mailto:ken@glxn.net">Ken Gullaksen</a> * @version $Revision: $ */
public class ConfigurationBuilder { // -------------------------------------------------------------------------------------|| // Class Members ----------------------------------------------------------------------|| // -------------------------------------------------------------------------------------||
Logger
/** * Logger */
private static final Logger log = Logger.getLogger(ConfigurationBuilder.class.getName());
Implementation class name of the default ExtensionLoader to be used
/** * Implementation class name of the default {@link ExtensionLoader} to be used */
private static final String EXTENSION_LOADER_IMPL = "org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader"; // -------------------------------------------------------------------------------------|| // Instance Members -------------------------------------------------------------------|| // -------------------------------------------------------------------------------------||
Loader mapping archive types to the appropriate underlying implementation
/** * Loader mapping archive types to the appropriate underlying implementation */
private ExtensionLoader extensionLoader;
ExecutorService used for all asynchronous operations
/** * {@link ExecutorService} used for all asynchronous operations */
private ExecutorService executorService;
ClassLoaders used for extension loading, adding resources, etc
/** * {@link ClassLoader}s used for extension loading, adding resources, etc */
private Iterable<ClassLoader> classLoaders; // -------------------------------------------------------------------------------------|| // Constructor ------------------------------------------------------------------------|| // -------------------------------------------------------------------------------------||
Creates a new builder initialized to defaults (null) values. Any properties not explicitly provided by the user will be defaulted during build().
/** * Creates a new builder initialized to defaults (null) values. Any properties not explicitly provided by the user * will be defaulted during {@link ConfigurationBuilder#build()}. */
public ConfigurationBuilder() { } // -------------------------------------------------------------------------------------|| // Functional Methods ----------------------------------------------------------------|| // -------------------------------------------------------------------------------------||
Returns:the extensionLoader
/** * @return the extensionLoader */
public ExtensionLoader getExtensionLoader() { return extensionLoader; }
Returns:the executorService
/** * @return the executorService */
public ExecutorService getExecutorService() { return executorService; }
Returns:
/** * @return */
public Iterable<ClassLoader> getClassLoaders() { return classLoaders; }
Sets the ExtensionLoader to be used, returning this instance
Params:
  • extensionLoader –
Returns:
/** * Sets the {@link ExtensionLoader} to be used, returning this instance * * @param extensionLoader * @return */
public ConfigurationBuilder extensionLoader(final ExtensionLoader extensionLoader) { this.extensionLoader = extensionLoader; return this; }
Sets the ExecutorService to be used, returning this instance
Params:
  • executorService –
Returns:
/** * Sets the {@link ExecutorService} to be used, returning this instance * * @param executorService * @return */
public ConfigurationBuilder executorService(final ExecutorService executorService) { this.executorService = executorService; return this; }
Sets the ClassLoader used in resolving extension implementations by the ExtensionLoader; other tasks requiring a CL by the Archive
Params:
  • classLoaders –
Returns:
/** * Sets the {@link ClassLoader} used in resolving extension implementations by the {@link ExtensionLoader}; other * tasks requiring a CL by the {@link Archive} * * @param classLoaders * @return */
public ConfigurationBuilder classLoaders(final Iterable<ClassLoader> classLoaders) { this.classLoaders = classLoaders; return this; }
Builds a new Configuration using the properties contained in this builder. In the case a property has not been specified, it will be defaulted according to the rules set forth in this ConfigurationBuilder's contract.
Returns:
/** * Builds a new {@link Configuration} using the properties contained in this builder. In the case a property has not * been specified, it will be defaulted according to the rules set forth in this {@link ConfigurationBuilder}'s * contract. * * @return */
public Configuration build() { // Make a new configuration and return it. return new Configuration(this); } // -------------------------------------------------------------------------------------|| // Internal Helper Methods -----------------------------------------------------------|| // -------------------------------------------------------------------------------------||
Sets properties to their default values if they haven't been explicitly provided by the user. If no ClassLoaders are specified, use the TCCL.
/** * Sets properties to their default values if they haven't been explicitly provided by the user. If no ClassLoaders * are specified, use the TCCL. */
void setDefaults() { // If no ClassLoaders are specified, use the TCCL // Ensure we default this BEFORE defaulting the extension loader, as // the loader needs a CL to be created if (this.getClassLoaders() == null) { final ClassLoader tccl = SecurityActions.getThreadContextClassLoader(); if (log.isLoggable(Level.FINER)) { log.finer("User has not defined an explicit " + ClassLoader.class.getSimpleName() + "; defaulting to the TCCL: " + tccl); } final Collection<ClassLoader> tcclCollection = new ArrayList<ClassLoader>(1); // Adjust for the bootstrap CL, which may be denoted as null in some JVM impls if (tccl != null) { tcclCollection.add(tccl); } else { tcclCollection.add(ClassLoader.getSystemClassLoader()); } this.classLoaders = tcclCollection; } // Adjust the CLs to be sure of no duplicate or null references (which may indicate // the bootstrap CL, so get to the system CL) final Collection<ClassLoader> adjustedCls = new HashSet<ClassLoader>(); for (ClassLoader cl : this.classLoaders) { // Adjust for null references if (cl == null) { cl = ClassLoader.getSystemClassLoader(); } // Add to the set, which will restrict duplicates adjustedCls.add(cl); } this.classLoaders = adjustedCls; // If no extension loader is present, create one if (getExtensionLoader() == null) { final ExtensionLoader loader = createDefaultExtensionLoader(); if (log.isLoggable(Level.FINER)) { log.finer("User has not defined an explicit " + ExtensionLoader.class.getSimpleName() + "; defaulting to " + loader); } this.extensionLoader(loader); } }
Obtains the default ExtensionLoader to be used if none is specified
Returns:
/** * Obtains the default {@link ExtensionLoader} to be used if none is specified * * @return */
ExtensionLoader createDefaultExtensionLoader() { // First find the right Class/ClassLoader final Class<?> extensionLoaderImplClass; try { extensionLoaderImplClass = ClassLoaderSearchUtil.findClassFromClassLoaders(EXTENSION_LOADER_IMPL, getClassLoaders()); } catch (final ClassNotFoundException cnfe) { throw new IllegalStateException( "Could not find extension loader impl class in any of the configured ClassLoaders", cnfe); } // Return return SecurityActions.newInstance(extensionLoaderImplClass, new Class<?>[] { Iterable.class }, new Object[] { this.getClassLoaders() }, ExtensionLoader.class); } }