Skip to content

Commit

Permalink
javadoc for default extensions loading strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Pazmino authored and Andrew Lee Rubinger committed May 31, 2011
1 parent d3bd9e4 commit b397b22
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
3 changes: 2 additions & 1 deletion api/src/main/java/org/jboss/shrinkwrap/api/Assignable.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
public interface Assignable
{
/**
* Wraps a Archive in a different 'view'.
* Wraps an Archive in a different 'view'.
* @see org.jboss.shrinkwrap.impl.base.ExtensionLoader
*
* @param <TYPE>
* @param clazz Extension interface to load
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public Configuration build()

/**
* Sets properties to their default values if they haven't been explicitly
* provided by the user
* provided by the user. If no ClassLoaders are specified, use the TCCL.
*/
void setDefaults()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
* ExtensionLoader
*
* Describes a way for the {@link Archive} to load extensions.
* If an implementation is not set in the {@link Domain}'s
* {@link Configuration}, {@link ServiceExtensionLoader} is set as the
* default strategy to load extensions.
*
* @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
* @author <a href="mailto:ken@glxn.net">Ken Gullaksen</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,31 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.logging.Logger;

import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.Assignable;
import org.jboss.shrinkwrap.api.ClassLoaderSearchUtilDelegator;
import org.jboss.shrinkwrap.api.Configuration;
import org.jboss.shrinkwrap.api.ConfigurationBuilder;
import org.jboss.shrinkwrap.api.ExtensionLoader;
import org.jboss.shrinkwrap.api.UnknownExtensionTypeException;
import org.jboss.shrinkwrap.api.UnknownExtensionTypeExceptionDelegator;

/**
* ServiceExtensionLoader
*
* This class is the default strategy to load extensions when an instance of
* {@link ExtensionLoader} is not provided to the {@link ConfigurationBuilder}
* and the {@link ConfigurationBuilder#build()} method is invoked. If the
* {@link ConfigurationBuilder} doesn't provide any {@link ClassLoader},
* {@link ConfigurationBuilder#build()} defaults to a one-element collection
* holding the TCCL. The {@link ServiceExtensionLoader#classLoaders} are used
* to find the provider-configuration file for the extension to be loaded in
* META-INF/services/. This provider-configuration file is used to make an
* instance of the SPI implementation and cached in
* {@link ServiceExtensionLoader#cache}.
*
* @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
* @author <a href="mailto:ken@glxn.net">Ken Gullaksen</a>
Expand Down Expand Up @@ -180,6 +194,16 @@ public boolean isOverriden(Class<?> extensionClass)
// Internal Helper Methods - Loading --------------------------------------------------||
//-------------------------------------------------------------------------------------||

/**
* Creates a new instance of a <code>extensionClass</code> implementation.
* The implementation class is found in a provider-configuration file
* in META-INF/services/
*
* @param <T>
* @param extensionClass
* @param archive
* @return an instance of the <code>extensionClass</code>' implementation.
*/
private <T extends Assignable> T createFromLoadExtension(Class<T> extensionClass, Archive<?> archive)
{
ExtensionWrapper extensionWrapper = loadExtensionMapping(extensionClass);
Expand All @@ -198,11 +222,27 @@ private <T extends Assignable> T createFromLoadExtension(Class<T> extensionClass
return createExtension(extensionImplClass, archive);
}

/**
* Loads the implementation class hold in
* {@link ExtensionWrapper#implementingClassName}
*
* @param <T>
* @param extensionWrapper
* @return
*/
private <T extends Assignable> Class<T> loadExtension(ExtensionWrapper extensionWrapper)
{
return loadExtensionClass(extensionWrapper.implementingClassName);
}

/**
* Finds the SPI configuration, wraps it into a {@link ExtensionWrapper} and
* loads it to {@link ServiceExtensionLoader#extensionMappings}.
*
* @param <T>
* @param extensionClass
* @return
*/
private <T extends Assignable> ExtensionWrapper loadExtensionMapping(Class<T> extensionClass)
{
final InputStream extensionStream = findExtensionImpl(extensionClass);
Expand All @@ -212,7 +252,17 @@ private <T extends Assignable> ExtensionWrapper loadExtensionMapping(Class<T> ex
return extensionWrapper;
}


/**
* Iterates through the classloaders to load the provider-configuration file
* for <code>extensionClass</code> in META-INF/services/ using its binary
* name.
*
* @param <T>
* @param extensionClass SPI type for which the configuration file is looked for
* @return An {@link InputStream} representing <code>extensionClass</code>'s configuration file
* @throws RuntimeException if it doesn't find a provider-configuration file for <code>extensionClass</code>
* @throws UnknownExtensionTypeExceptionDelegator
*/
private <T extends Assignable> InputStream findExtensionImpl(final Class<T> extensionClass)
{
try
Expand All @@ -237,6 +287,16 @@ private <T extends Assignable> InputStream findExtensionImpl(final Class<T> exte
}
}

/**
* Wraps the provider-configuration file <code>extensionStream</code>, the
* SPI <code>extensionClass</code> and its implementation class name into
* a {@link ExtensionWrapper} instance.
*
* @param <T>
* @param extensionStream - a bytes stream representation of the provider-configuration file
* @param extensionClass - SPI type
* @return a {@link ExtensionWrapper} instance
*/
private <T extends Assignable> ExtensionWrapper loadExtensionWrapper(final InputStream extensionStream, Class<T> extensionClass)
{
Properties properties = new Properties();
Expand All @@ -262,6 +322,16 @@ private <T extends Assignable> ExtensionWrapper loadExtensionWrapper(final Input
return new ExtensionWrapper(implementingClassName, map, extensionClass);
}

/**
* Delegates class loading of <code>extensionClassName</code> to
* {@link ClassLoaderSearchUtilDelegator#findClassFromClassLoaders(String, Iterable)}
* passing the <code>extensionClassName</code> and the instance's
* <code>classLoaders</code>.
*
* @param <T>
* @param extensionClassName
* @return
*/
@SuppressWarnings("unchecked")
private <T extends Assignable> Class<T> loadExtensionClass(String extensionClassName)
{
Expand All @@ -276,6 +346,16 @@ private <T extends Assignable> Class<T> loadExtensionClass(String extensionClass
}
}

/**
* Creates an instance of <code>extensionImplClass</code> using
* <code>archive</code> as the parameter for its one-argument list
* constructor.
*
* @param <T>
* @param extensionImplClass
* @param archive
* @return
*/
private <T extends Assignable> T createExtension(Class<T> extensionImplClass, Archive<?> archive)
{

Expand Down Expand Up @@ -315,6 +395,14 @@ private <T extends Assignable> T createExtension(Class<T> extensionImplClass, Ar
return extension;
}

/**
* Finds a constructor with a one-argument list's element which implements
* {@link Archive}.
*
* @param <T>
* @param extensionImplClass - Implementation of {@link Assignable} with a one-argument list's element which implements {@link Archive}.
* @return
*/
@SuppressWarnings("unchecked")
private <T extends Assignable> Constructor<T> findConstructor(Class<T> extensionImplClass)
{
Expand Down

0 comments on commit b397b22

Please sign in to comment.