mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 17:26:22 +01:00
added module to register servlets and filters by new WebElement annotation
This commit is contained in:
@@ -66,6 +66,7 @@ import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import sonia.scm.filter.WebElementModule;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -255,6 +256,7 @@ public class ScmContextListener extends GuiceServletContextListener
|
||||
moduleList.add(new ScmEventBusModule());
|
||||
moduleList.add(new EagerSingletonModule());
|
||||
moduleList.add(ShiroWebModule.guiceFilterModule());
|
||||
moduleList.add(new WebElementModule(pluginLoader));
|
||||
moduleList.add(new ScmServletModule(servletCtx, pluginLoader, overrides));
|
||||
moduleList.add(
|
||||
new ScmSecurityModule(servletCtx, pluginLoader.getExtensionProcessor())
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
package sonia.scm.filter;
|
||||
|
||||
import sonia.scm.plugin.WebElementDescriptor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @param <T>
|
||||
*/
|
||||
public final class TypedWebElementDescriptor<T>
|
||||
{
|
||||
private final Class<T> clazz;
|
||||
private final WebElementDescriptor descriptor;
|
||||
|
||||
public TypedWebElementDescriptor(Class<T> clazz,
|
||||
WebElementDescriptor descriptor)
|
||||
{
|
||||
this.clazz = clazz;
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public Class<T> getClazz()
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public WebElementDescriptor getDescriptor()
|
||||
{
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.filter;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.Priorities;
|
||||
import sonia.scm.plugin.PluginLoader;
|
||||
import sonia.scm.plugin.WebElementDescriptor;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public final class WebElementCollector
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for WebElementCollector
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(WebElementCollector.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param elements
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private WebElementCollector(Iterable<WebElementDescriptor> elements)
|
||||
{
|
||||
List<TypedWebElementDescriptor<? extends Filter>> fl = Lists.newArrayList();
|
||||
List<TypedWebElementDescriptor<? extends HttpServlet>> sl =
|
||||
Lists.newArrayList();
|
||||
|
||||
for (WebElementDescriptor element : elements)
|
||||
{
|
||||
if (Filter.class.isAssignableFrom(element.getClazz()))
|
||||
{
|
||||
fl.add(
|
||||
new TypedWebElementDescriptor<>(
|
||||
(Class<? extends Filter>) element.getClazz(), element));
|
||||
}
|
||||
else if (Servlet.class.isAssignableFrom(element.getClazz()))
|
||||
{
|
||||
sl.add(
|
||||
new TypedWebElementDescriptor<>(
|
||||
(Class<? extends HttpServlet>) element.getClazz(), element));
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn(
|
||||
"found class {} witch is annotated with webelement annotation, but is neither an filter or servlet",
|
||||
element.getClazz());
|
||||
}
|
||||
}
|
||||
|
||||
TypedWebElementDescriptorOrdering ordering =
|
||||
new TypedWebElementDescriptorOrdering();
|
||||
|
||||
filters = ordering.immutableSortedCopy(fl);
|
||||
servlets = ordering.immutableSortedCopy(sl);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param loader
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static WebElementCollector collect(PluginLoader loader)
|
||||
{
|
||||
return new WebElementCollector(
|
||||
loader.getExtensionProcessor().getWebElements());
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Iterable<TypedWebElementDescriptor<? extends Filter>> getFilters()
|
||||
{
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Iterable<TypedWebElementDescriptor<? extends HttpServlet>> getServlets()
|
||||
{
|
||||
return servlets;
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 15/02/01
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class TypedWebElementDescriptorOrdering
|
||||
extends Ordering<TypedWebElementDescriptor<?>>
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param left
|
||||
* @param right
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int compare(TypedWebElementDescriptor<?> left,
|
||||
TypedWebElementDescriptor<?> right)
|
||||
{
|
||||
return Ints.compare(Priorities.getPriority(left.getClazz()),
|
||||
Priorities.getPriority(right.getClazz()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Iterable<TypedWebElementDescriptor<? extends Filter>> filters;
|
||||
|
||||
/** Field description */
|
||||
private final Iterable<TypedWebElementDescriptor<? extends HttpServlet>> servlets;
|
||||
}
|
||||
164
scm-webapp/src/main/java/sonia/scm/filter/WebElementModule.java
Normal file
164
scm-webapp/src/main/java/sonia/scm/filter/WebElementModule.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.filter;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.plugin.PluginLoader;
|
||||
import sonia.scm.plugin.WebElementDescriptor;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class WebElementModule extends ServletModule
|
||||
{
|
||||
|
||||
/**
|
||||
* the logger for WebElementModule
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(WebElementModule.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param pluginLoader
|
||||
*/
|
||||
public WebElementModule(PluginLoader pluginLoader)
|
||||
{
|
||||
collector = WebElementCollector.collect(pluginLoader);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected void configureServlets()
|
||||
{
|
||||
for (TypedWebElementDescriptor<? extends Filter> f : collector.getFilters())
|
||||
{
|
||||
bindFilter(f);
|
||||
}
|
||||
|
||||
for (TypedWebElementDescriptor<? extends HttpServlet> s :
|
||||
collector.getServlets())
|
||||
{
|
||||
bindServlet(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param filter
|
||||
*/
|
||||
private void bindFilter(TypedWebElementDescriptor<? extends Filter> filter)
|
||||
{
|
||||
Class<? extends Filter> clazz = filter.getClazz();
|
||||
|
||||
logger.info("bind filter {} to filter chain", clazz);
|
||||
|
||||
// filters must be in singleton scope
|
||||
bind(clazz).in(Scopes.SINGLETON);
|
||||
|
||||
WebElementDescriptor opts = filter.getDescriptor();
|
||||
FilterKeyBindingBuilder builder;
|
||||
|
||||
if (opts.isRegex())
|
||||
{
|
||||
builder = filterRegex(opts.getPattern(), opts.getMorePatterns());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder = filter(opts.getPattern(), opts.getMorePatterns());
|
||||
}
|
||||
|
||||
// TODO handle init parameters
|
||||
builder.through(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param servlet
|
||||
*/
|
||||
private void bindServlet(
|
||||
TypedWebElementDescriptor<? extends HttpServlet> servlet)
|
||||
{
|
||||
Class<? extends HttpServlet> clazz = servlet.getClazz();
|
||||
|
||||
logger.info("bind servlet {} to servlet chain", clazz);
|
||||
|
||||
// filters must be in singleton scope
|
||||
bind(clazz).in(Scopes.SINGLETON);
|
||||
|
||||
WebElementDescriptor opts = servlet.getDescriptor();
|
||||
ServletKeyBindingBuilder builder;
|
||||
|
||||
if (opts.isRegex())
|
||||
{
|
||||
builder = serveRegex(opts.getPattern(), opts.getMorePatterns());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder = serve(opts.getPattern(), opts.getMorePatterns());
|
||||
}
|
||||
|
||||
// TODO handle init parameters
|
||||
builder.with(clazz);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final WebElementCollector collector;
|
||||
}
|
||||
@@ -113,6 +113,20 @@ public class DefaultExtensionProcessor implements ExtensionProcessor
|
||||
logger.info("bound extensions in {}", sw.stop());
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Iterable<WebElementDescriptor> getWebElements()
|
||||
{
|
||||
return collector.getWebElements();
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
|
||||
@@ -205,6 +205,17 @@ public final class ExtensionCollector
|
||||
return restResources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Set<WebElementDescriptor> getWebElements()
|
||||
{
|
||||
return webElements;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -263,18 +274,22 @@ public final class ExtensionCollector
|
||||
|
||||
restProviders.addAll(Lists.newArrayList(module.getRestProviders()));
|
||||
restResources.addAll(Lists.newArrayList(module.getRestResources()));
|
||||
Iterables.addAll(webElements, module.getWebElements());
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final Set<Class> looseExtensions = Sets.newHashSet();
|
||||
private final Set<WebElementDescriptor> webElements = Sets.newHashSet();
|
||||
|
||||
/** Field description */
|
||||
private final Set<Class> restResources = Sets.newHashSet();
|
||||
|
||||
/** Field description */
|
||||
private final Set<Class> restProviders = Sets.newHashSet();
|
||||
|
||||
/** Field description */
|
||||
private final Set<Class> restResources = Sets.newHashSet();
|
||||
private final Set<Class> looseExtensions = Sets.newHashSet();
|
||||
|
||||
/** Field description */
|
||||
private final Multimap<ExtensionPointElement, Class> extensions =
|
||||
|
||||
Reference in New Issue
Block a user