support for non auto binding extension points and treat guice modules as normal extension points

This commit is contained in:
Sebastian Sdorra
2014-12-19 17:41:46 +01:00
parent f64f29bb2e
commit bfd67c5aef
9 changed files with 93 additions and 88 deletions

View File

@@ -52,4 +52,5 @@ import java.lang.annotation.Target;
public @interface ExtensionPoint public @interface ExtensionPoint
{ {
boolean multi() default true; boolean multi() default true;
boolean autoBind() default true;
} }

View File

@@ -65,13 +65,15 @@ public final class ExtensionPointElement
* @param clazz * @param clazz
* @param description * @param description
* @param multiple * @param multiple
* @param autoBind
*/ */
public ExtensionPointElement(Class<?> clazz, String description, public ExtensionPointElement(Class<?> clazz, String description,
boolean multiple) boolean multiple, boolean autoBind)
{ {
this.clazz = clazz; this.clazz = clazz;
this.description = description; this.description = description;
this.multiple = multiple; this.multiple = multiple;
this.autoBind = autoBind;
} }
//~--- methods -------------------------------------------------------------- //~--- methods --------------------------------------------------------------
@@ -101,7 +103,8 @@ public final class ExtensionPointElement
return Objects.equal(clazz, other.clazz) return Objects.equal(clazz, other.clazz)
&& Objects.equal(description, other.description) && Objects.equal(description, other.description)
&& Objects.equal(multiple, other.multiple); && Objects.equal(multiple, other.multiple)
&& Objects.equal(autoBind, other.autoBind);
} }
/** /**
@@ -113,7 +116,7 @@ public final class ExtensionPointElement
@Override @Override
public int hashCode() public int hashCode()
{ {
return Objects.hashCode(clazz, description, multiple); return Objects.hashCode(clazz, description, multiple, autoBind);
} }
/** /**
@@ -130,6 +133,7 @@ public final class ExtensionPointElement
.add("class", clazz) .add("class", clazz)
.add("description", description) .add("description", description)
.add("multiple", multiple) .add("multiple", multiple)
.add("autoBind", autoBind)
.toString(); .toString();
//J+ //J+
} }
@@ -158,6 +162,17 @@ public final class ExtensionPointElement
return description; return description;
} }
/**
* Method description
*
*
* @return
*/
public boolean isAutoBind()
{
return autoBind;
}
/** /**
* Method description * Method description
* *
@@ -181,4 +196,7 @@ public final class ExtensionPointElement
/** Field description */ /** Field description */
@XmlElement(name = "multi") @XmlElement(name = "multi")
private boolean multiple = true; private boolean multiple = true;
/** Field description */
private boolean autoBind = true;
} }

View File

@@ -56,14 +56,6 @@ public interface PluginLoader
*/ */
public ExtensionProcessor getExtensionProcessor(); public ExtensionProcessor getExtensionProcessor();
/**
* Method description
*
*
* @return
*/
public Collection<Module> getInjectionModules();
/** /**
* Method description * Method description
* *

View File

@@ -36,4 +36,8 @@ http://bitbucket.org/sdorra/scm-manager
<extension-point> <extension-point>
<class>javax.servlet.http.HttpSessionListener</class> <class>javax.servlet.http.HttpSessionListener</class>
</extension-point> </extension-point>
<extension-point>
<class>com.google.inject.Module</class>
<autoBind>false</autoBind>
</extension-point>
</module> </module>

View File

@@ -78,9 +78,9 @@ public class ScmModuleTest
assertThat( assertThat(
module.getExtensionPoints(), module.getExtensionPoints(),
containsInAnyOrder( containsInAnyOrder(
new ExtensionPointElement(String.class, "ext01", true), new ExtensionPointElement(String.class, "ext01", true, true),
new ExtensionPointElement(Long.class, "ext02", true), new ExtensionPointElement(Long.class, "ext02", true, true),
new ExtensionPointElement(Integer.class, "ext03", false) new ExtensionPointElement(Integer.class, "ext03", false, true)
) )
); );
assertThat( assertThat(

View File

@@ -36,6 +36,7 @@ package sonia.scm;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
@@ -50,6 +51,7 @@ import org.slf4j.LoggerFactory;
import sonia.scm.cache.CacheManager; import sonia.scm.cache.CacheManager;
import sonia.scm.group.GroupManager; import sonia.scm.group.GroupManager;
import sonia.scm.plugin.DefaultPluginLoader; import sonia.scm.plugin.DefaultPluginLoader;
import sonia.scm.plugin.ExtensionProcessor;
import sonia.scm.plugin.PluginWrapper; import sonia.scm.plugin.PluginWrapper;
import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManager;
import sonia.scm.store.StoreFactory; import sonia.scm.store.StoreFactory;
@@ -204,6 +206,33 @@ public class ScmContextListener extends GuiceServletContextListener
return globalInjector; return globalInjector;
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param ep
* @param moduleList
*/
private void appendModules(ExtensionProcessor ep, List<Module> moduleList)
{
for (Class<Module> module : ep.byExtensionPoint(Module.class))
{
try
{
logger.info("add module {}", module);
moduleList.add(module.newInstance());
}
catch (IllegalAccessException | InstantiationException ex)
{
throw Throwables.propagate(ex);
}
}
}
//~--- get methods ----------------------------------------------------------
/** /**
* Method description * Method description
* *
@@ -228,7 +257,7 @@ public class ScmContextListener extends GuiceServletContextListener
moduleList.add(ShiroWebModule.guiceFilterModule()); moduleList.add(ShiroWebModule.guiceFilterModule());
moduleList.add(new ScmServletModule(servletCtx, pluginLoader, overrides)); moduleList.add(new ScmServletModule(servletCtx, pluginLoader, overrides));
moduleList.add(new ScmSecurityModule(servletCtx)); moduleList.add(new ScmSecurityModule(servletCtx));
moduleList.addAll(pluginLoader.getInjectionModules()); appendModules(pluginLoader.getExtensionProcessor(), moduleList);
moduleList.addAll(overrides.getModules()); moduleList.addAll(overrides.getModules());
SCMContextProvider ctx = SCMContext.getContext(); SCMContextProvider ctx = SCMContext.getContext();

View File

@@ -123,18 +123,6 @@ public class DefaultPluginLoader implements PluginLoader
return extensionProcessor; return extensionProcessor;
} }
/**
* Method description
*
*
* @return
*/
@Override
public Set<Module> getInjectionModules()
{
return ImmutableSet.copyOf(collector.getInjectionModules());
}
/** /**
* Method description * Method description
* *

View File

@@ -93,6 +93,29 @@ public final class ExtensionBinder
logger.info("bind extensions to extension points"); logger.info("bind extensions to extension points");
for (ExtensionPointElement epe : collector.getExtensionPointElements()) for (ExtensionPointElement epe : collector.getExtensionPointElements())
{
bindExtensionPoint(collector, epe);
}
logger.info("bind loose extensions");
bindLooseExtensions(collector.getLooseExtensions());
logger.info("bind rest providers");
bindRestProviders(collector.getRestProviders());
logger.info("bind rest resources");
bindRestResource(collector.getRestResources());
}
/**
* Method description
*
*
* @param collector
* @param epe
*/
private void bindExtensionPoint(ExtensionCollector collector,
ExtensionPointElement epe)
{
if (epe.isAutoBind())
{ {
if (epe.isMultiple()) if (epe.isMultiple())
{ {
@@ -113,13 +136,10 @@ public final class ExtensionBinder
} }
} }
} }
else
logger.info("bind loose extensions"); {
bindLooseExtensions(collector.getLooseExtensions()); logger.debug("bind type of {} is manual", epe.getClazz());
logger.info("bind rest providers"); }
bindRestProviders(collector.getRestProviders());
logger.info("bind rest resources");
bindRestResource(collector.getRestResources());
} }
/** /**

View File

@@ -39,10 +39,6 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.inject.Module;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
@@ -60,14 +56,6 @@ import java.util.Set;
public final class ExtensionCollector public final class ExtensionCollector
{ {
/**
* the logger for ExtensionCollector
*/
private static final Logger logger =
LoggerFactory.getLogger(ExtensionCollector.class);
//~--- constructors ---------------------------------------------------------
/** /**
* Constructs ... * Constructs ...
* *
@@ -100,9 +88,12 @@ public final class ExtensionCollector
public Collection<Class> byExtensionPoint(ExtensionPointElement epe) public Collection<Class> byExtensionPoint(ExtensionPointElement epe)
{ {
Collection<Class> collection = extensions.get(epe); Collection<Class> collection = extensions.get(epe);
if ( collection == null ){
if (collection == null)
{
collection = Collections.EMPTY_SET; collection = Collections.EMPTY_SET;
} }
return collection; return collection;
} }
@@ -181,17 +172,6 @@ public final class ExtensionCollector
return extensions; return extensions;
} }
/**
* Method description
*
*
* @return
*/
public Set<Module> getInjectionModules()
{
return injectionModules;
}
/** /**
* Method description * Method description
* *
@@ -254,24 +234,6 @@ public final class ExtensionCollector
} }
} }
/**
* Method description
*
*
* @param extension
*/
private void appendModule(Class extension)
{
try
{
injectionModules.add((Module) extension.newInstance());
}
catch (IllegalAccessException | InstantiationException ex)
{
logger.error("could not create instance of module", ex);
}
}
/** /**
* Method description * Method description
* *
@@ -281,17 +243,10 @@ public final class ExtensionCollector
private void collectExtensions(ScmModule module) private void collectExtensions(ScmModule module)
{ {
for (Class extension : module.getExtensions()) for (Class extension : module.getExtensions())
{
if (Module.class.isAssignableFrom(extension))
{
appendModule(extension);
}
else
{ {
appendExtension(extension); appendExtension(extension);
} }
} }
}
/** /**
* Method description * Method description
@@ -305,6 +260,7 @@ public final class ExtensionCollector
{ {
extensionPointIndex.put(epe.getClazz(), epe); extensionPointIndex.put(epe.getClazz(), epe);
} }
restProviders.addAll(Lists.newArrayList(module.getRestProviders())); restProviders.addAll(Lists.newArrayList(module.getRestProviders()));
restResources.addAll(Lists.newArrayList(module.getRestResources())); restResources.addAll(Lists.newArrayList(module.getRestResources()));
} }
@@ -314,9 +270,6 @@ public final class ExtensionCollector
/** Field description */ /** Field description */
private final Set<Class> looseExtensions = Sets.newHashSet(); private final Set<Class> looseExtensions = Sets.newHashSet();
/** Field description */
private final Set<Module> injectionModules = Sets.newHashSet();
/** Field description */ /** Field description */
private final Set<Class> restProviders = Sets.newHashSet(); private final Set<Class> restProviders = Sets.newHashSet();