Merge pull request #1101 from scm-manager/feature/requires_for_webelement

Feature/requires for webelement
This commit is contained in:
eheimbuch
2020-04-21 12:55:13 +02:00
committed by GitHub
13 changed files with 228 additions and 279 deletions

View File

@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Add iconStyle + onClick option and story shot for icon component ([#1100](https://github.com/scm-manager/scm-manager/pull/1100))
- Making WebElements (Servlet or Filter) optional by using the `@Requires` annotation ([#1101](https://github.com/scm-manager/scm-manager/pull/1101))
### Changed
- Removed the `requires` attribute on the `@Extension` annotation and instead create a new `@Requires` annotation ([#1097](https://github.com/scm-manager/scm-manager/pull/1097))

View File

@@ -26,6 +26,7 @@ package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -43,12 +44,12 @@ import java.util.Set;
* @since 2.0.0
*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
@XmlAccessorType(XmlAccessType.FIELD)
public final class ClassElement {
@NoArgsConstructor(access = AccessLevel.PACKAGE)
public class ClassElement {
@XmlElement(name = "class")
private String clazz;
private String description;

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
@@ -76,5 +76,5 @@ public interface ExtensionProcessor
*
* @return collected web elements
*/
public Iterable<WebElementDescriptor> getWebElements();
public Iterable<WebElementExtension> getWebElements();
}

View File

@@ -21,155 +21,60 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import sonia.scm.xml.XmlArrayStringAdapter;
//~--- JDK imports ------------------------------------------------------------
import java.util.Arrays;
import java.util.Objects;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Arrays;
/**
* Descriptor for web elements such as filter or servlets. A web element can be registered by using the
* Descriptor for web elements such as filter or servlets. A web element can be registered by using the
* {@link sonia.scm.filter.WebElement} annotation.
*
*
* @author Sebastian Sdorra
* @since 2.0.0
*/
@Getter
@ToString
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@XmlRootElement(name = "web-element")
@XmlAccessorType(XmlAccessType.FIELD)
public final class WebElementDescriptor
{
@NoArgsConstructor(access = AccessLevel.PACKAGE)
public final class WebElementDescriptor extends ClassElement {
/**
* Constructs ...
*
*/
WebElementDescriptor() {}
/**
* Constructs ...
*
*
* @param clazz
* @param pattern
* @param morePatterns
* @param regex
*/
public WebElementDescriptor(Class<?> clazz, String pattern,
String[] morePatterns, boolean regex)
{
this.clazz = clazz;
this.pattern = pattern;
this.morePatterns = morePatterns;
this.regex = regex;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public Class<?> getClazz()
{
return clazz;
}
/**
* Method description
*
*
* @return
*/
public String[] getMorePatterns()
{
String[] patterns;
if (morePatterns != null)
{
patterns = Arrays.copyOf(morePatterns, morePatterns.length);
}
else
{
patterns = new String[0];
}
return patterns;
}
/**
* Method description
*
*
* @return
*/
public String getPattern()
{
return pattern;
}
/**
* Method description
*
*
* @return
*/
public boolean isRegex()
{
return regex;
}
@Override
public int hashCode() {
return Objects.hash(clazz, pattern, Arrays.hashCode(morePatterns), regex);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final WebElementDescriptor other = (WebElementDescriptor) obj;
return Objects.equals(clazz, other.clazz)
&& Objects.equals(pattern, other.pattern)
&& Arrays.equals(morePatterns, other.morePatterns)
&& this.regex == other.regex;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@XmlElement(name = "class")
private Class<?> clazz;
/** Field description */
@XmlJavaTypeAdapter(XmlArrayStringAdapter.class)
private String[] morePatterns;
/** Field description */
@XmlElement(name = "value")
private String pattern;
/** Field description */
@XmlJavaTypeAdapter(XmlArrayStringAdapter.class)
private String[] morePatterns = {};
private boolean regex = false;
public String[] getMorePatterns() {
String[] patterns;
if (morePatterns != null) {
patterns = Arrays.copyOf(morePatterns, morePatterns.length);
} else {
patterns = new String[0];
}
return patterns;
}
}

View File

@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.plugin;
import lombok.Value;
/**
* WebElementExtension can be a servlet or filter which is ready to bind.
* Those extensions are loaded by the {@link ExtensionProcessor} from a {@link WebElementDescriptor}.
*
* We don't know if we can load the defined class from the descriptor, because the class could be optional
* (annotated with {@link Requires}). So we have to load the class as string with {@link WebElementDescriptor} and when
* we know that it is safe to load the class (all requirements are fulfilled), we will create our WebElementExtension.
*
* @since 2.0.0
*/
@Value
public class WebElementExtension {
Class<?> clazz;
WebElementDescriptor descriptor;
}

View File

@@ -0,0 +1,77 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.plugin;
import org.junit.jupiter.api.Test;
import javax.xml.bind.JAXB;
import java.io.StringReader;
import static org.assertj.core.api.Assertions.assertThat;
class WebElementDescriptorTest {
private static final String XML_1 = String.join("\n",
"<web-element>",
" <class>com.hitchhiker.SpaceShip</class>",
" <value>/space/*</value>",
" <regex>false</regex>",
" <morePatterns>/ship/*,/star/*</morePatterns>",
" <requires>scm-magrathea-plugin</requires>",
" <requires>scm-earth-plugin</requires>",
"</web-element>"
);
private static final String XML_2 = String.join("\n",
"<web-element>",
" <class>com.hitchhiker.SpaceShip</class>",
" <value>/space/.*</value>",
" <regex>true</regex>",
"</web-element>"
);
@Test
void shouldUnmarshall() {
WebElementDescriptor descriptor = unmarshal(XML_1);
assertThat(descriptor.getClazz()).isEqualTo("com.hitchhiker.SpaceShip");
assertThat(descriptor.getPattern()).isEqualTo("/space/*");
assertThat(descriptor.getMorePatterns()).containsExactly("/ship/*", "/star/*");
assertThat(descriptor.isRegex()).isFalse();
assertThat(descriptor.getRequires()).containsExactlyInAnyOrder("scm-magrathea-plugin", "scm-earth-plugin");
}
@Test
void shouldUnmarshallWithoutMorePatterns() {
WebElementDescriptor descriptor = unmarshal(XML_2);
assertThat(descriptor.getClazz()).isEqualTo("com.hitchhiker.SpaceShip");
assertThat(descriptor.getMorePatterns()).isEmpty();
assertThat(descriptor.isRegex()).isTrue();
}
private WebElementDescriptor unmarshal(String content) {
return JAXB.unmarshal(new StringReader(content), WebElementDescriptor.class);
}
}

View File

@@ -21,11 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.filter;
import java.util.Objects;
import lombok.Value;
import sonia.scm.plugin.WebElementDescriptor;
/**
@@ -34,48 +33,8 @@ import sonia.scm.plugin.WebElementDescriptor;
* @param <T>
* @since 2.0.0
*/
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;
}
@Override
public int hashCode() {
return Objects.hash(clazz, descriptor);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TypedWebElementDescriptor other = (TypedWebElementDescriptor) obj;
return Objects.equals(clazz, other.clazz)
&& Objects.equals(descriptor, other.descriptor);
}
@Value
public class TypedWebElementDescriptor<T> {
Class<T> clazz;
WebElementDescriptor descriptor;
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.filter;
//~--- non-JDK imports --------------------------------------------------------
@@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory;
import sonia.scm.Priorities;
import sonia.scm.plugin.PluginLoader;
import sonia.scm.plugin.WebElementDescriptor;
import sonia.scm.plugin.WebElementExtension;
//~--- JDK imports ------------------------------------------------------------
@@ -67,25 +67,24 @@ public final class WebElementCollector
* @param elements
*/
@SuppressWarnings("unchecked")
private WebElementCollector(Iterable<WebElementDescriptor> elements)
private WebElementCollector(Iterable<WebElementExtension> elements)
{
List<TypedWebElementDescriptor<? extends Filter>> fl = Lists.newArrayList();
List<TypedWebElementDescriptor<? extends HttpServlet>> sl =
Lists.newArrayList();
List<TypedWebElementDescriptor<Filter>> fl = Lists.newArrayList();
List<TypedWebElementDescriptor<HttpServlet>> sl = Lists.newArrayList();
for (WebElementDescriptor element : elements)
for (WebElementExtension element : elements)
{
if (Filter.class.isAssignableFrom(element.getClazz()))
{
fl.add(
new TypedWebElementDescriptor<>(
(Class<? extends Filter>) element.getClazz(), element));
(Class<Filter>) element.getClazz(), element.getDescriptor()));
}
else if (Servlet.class.isAssignableFrom(element.getClazz()))
{
sl.add(
new TypedWebElementDescriptor<>(
(Class<? extends HttpServlet>) element.getClazz(), element));
(Class<HttpServlet>) element.getClazz(), element.getDescriptor()));
}
else
{
@@ -95,8 +94,7 @@ public final class WebElementCollector
}
}
TypedWebElementDescriptorOrdering ordering =
new TypedWebElementDescriptorOrdering();
TypedWebElementDescriptorOrdering ordering = new TypedWebElementDescriptorOrdering();
filters = ordering.immutableSortedCopy(fl);
servlets = ordering.immutableSortedCopy(sl);
@@ -126,7 +124,7 @@ public final class WebElementCollector
*
* @return
*/
public Iterable<TypedWebElementDescriptor<? extends Filter>> getFilters()
public Iterable<TypedWebElementDescriptor<Filter>> getFilters()
{
return filters;
}
@@ -137,7 +135,7 @@ public final class WebElementCollector
*
* @return
*/
public Iterable<TypedWebElementDescriptor<? extends HttpServlet>> getServlets()
public Iterable<TypedWebElementDescriptor<HttpServlet>> getServlets()
{
return servlets;
}
@@ -177,8 +175,8 @@ public final class WebElementCollector
//~--- fields ---------------------------------------------------------------
/** Field description */
private final Iterable<TypedWebElementDescriptor<? extends Filter>> filters;
private final Iterable<TypedWebElementDescriptor<Filter>> filters;
/** Field description */
private final Iterable<TypedWebElementDescriptor<? extends HttpServlet>> servlets;
private final Iterable<TypedWebElementDescriptor<HttpServlet>> servlets;
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.filter;
//~--- non-JDK imports --------------------------------------------------------
@@ -44,60 +44,36 @@ import javax.servlet.http.HttpServlet;
*
* @author Sebastian Sdorra
*/
public class WebElementModule extends ServletModule
{
public class WebElementModule extends ServletModule {
/**
* the logger for WebElementModule
*/
private static final Logger logger =
LoggerFactory.getLogger(WebElementModule.class);
private static final Logger LOG = 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())
for (TypedWebElementDescriptor<Filter> f : collector.getFilters())
{
bindFilter(f);
}
for (TypedWebElementDescriptor<? extends HttpServlet> s :
collector.getServlets())
for (TypedWebElementDescriptor<HttpServlet> s : collector.getServlets())
{
bindServlet(s);
}
}
/**
* Method description
*
*
* @param filter
*/
private void bindFilter(TypedWebElementDescriptor<? extends Filter> filter)
{
Class<? extends Filter> clazz = filter.getClazz();
private void bindFilter(TypedWebElementDescriptor<Filter> filter) {
Class<Filter> clazz = filter.getClazz();
logger.info("bind filter {} to filter chain", clazz);
LOG.info("bind filter {} to filter chain", clazz);
// filters must be in singleton scope
bind(clazz).in(Scopes.SINGLETON);
@@ -105,12 +81,13 @@ public class WebElementModule extends ServletModule
WebElementDescriptor opts = filter.getDescriptor();
FilterKeyBindingBuilder builder;
if (opts.isRegex())
{
if (opts.isRegex()) {
LOG.debug("bind regex filter {} to {} and {}", clazz, opts.getPattern(), opts.getMorePatterns());
builder = filterRegex(opts.getPattern(), opts.getMorePatterns());
}
else
{
LOG.debug("bind glob filter {} to {} and {}", clazz, opts.getPattern(), opts.getMorePatterns());
builder = filter(opts.getPattern(), opts.getMorePatterns());
}
@@ -118,18 +95,10 @@ public class WebElementModule extends ServletModule
builder.through(clazz);
}
/**
* Method description
*
*
* @param servlet
*/
private void bindServlet(
TypedWebElementDescriptor<? extends HttpServlet> servlet)
{
Class<? extends HttpServlet> clazz = servlet.getClazz();
private void bindServlet(TypedWebElementDescriptor<HttpServlet> servlet) {
Class<HttpServlet> clazz = servlet.getClazz();
logger.info("bind servlet {} to servlet chain", clazz);
LOG.info("bind servlet {} to servlet chain", clazz);
// filters must be in singleton scope
bind(clazz).in(Scopes.SINGLETON);
@@ -137,12 +106,11 @@ public class WebElementModule extends ServletModule
WebElementDescriptor opts = servlet.getDescriptor();
ServletKeyBindingBuilder builder;
if (opts.isRegex())
{
if (opts.isRegex()) {
LOG.debug("bind regex servlet {} to {} and {}", clazz, opts.getPattern(), opts.getMorePatterns());
builder = serveRegex(opts.getPattern(), opts.getMorePatterns());
}
else
{
} else {
LOG.debug("bind glob servlet {} to {} and {}", clazz, opts.getPattern(), opts.getMorePatterns());
builder = serve(opts.getPattern(), opts.getMorePatterns());
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.lifecycle.modules;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -193,7 +193,7 @@ class ScmServletModule extends ServletModule {
// bind sslcontext provider
bind(SSLContext.class).toProvider(SSLContextProvider.class);
// bind ahc
Multibinder<ContentTransformer> transformers =
Multibinder.newSetBinder(binder(), ContentTransformer.class);
@@ -207,7 +207,7 @@ class ScmServletModule extends ServletModule {
// bind new hook api
bind(HookContextFactory.class);
bind(HookEventFacade.class);
// bind user-agent parser
bind(UserAgentParser.class);
@@ -215,7 +215,7 @@ class ScmServletModule extends ServletModule {
if ("true".equalsIgnoreCase(System.getProperty(SYSTEM_PROPERTY_DEBUG_HTTP))) {
filter(PATTERN_ALL).through(LoggingFilter.class);
}
// debug servlet
serve(PATTERN_DEBUG).with(DebugServlet.class);

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
@@ -115,7 +115,7 @@ public class DefaultExtensionProcessor implements ExtensionProcessor
* @return
*/
@Override
public Iterable<WebElementDescriptor> getWebElements()
public Iterable<WebElementExtension> getWebElements()
{
return collector.getWebElements();
}

View File

@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
@@ -29,25 +29,17 @@ package sonia.scm.plugin;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------
import javax.servlet.ServletContext;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
//~--- JDK imports ------------------------------------------------------------
/**
*
@@ -62,10 +54,6 @@ public class DefaultPluginLoader implements PluginLoader
/** Field description */
public static final String PATH_PLUGINCONFIG = "META-INF/scm/plugin.xml";
/** the logger for DefaultPluginLoader */
private static final Logger logger =
LoggerFactory.getLogger(DefaultPluginLoader.class);
//~--- constructors ---------------------------------------------------------
/**
@@ -90,7 +78,7 @@ public class DefaultPluginLoader implements PluginLoader
modules = getInstalled(parent, context, PATH_MODULECONFIG);
collector = new ExtensionCollector(parent, modules, installedPlugins);
ExtensionCollector collector = new ExtensionCollector(parent, modules, installedPlugins);
extensionProcessor = new DefaultExtensionProcessor(collector);
}
catch (IOException | JAXBException ex)
@@ -198,9 +186,6 @@ public class DefaultPluginLoader implements PluginLoader
//~--- fields ---------------------------------------------------------------
/** Field description */
private final ExtensionCollector collector;
/** Field description */
private final ExtensionProcessor extensionProcessor;

View File

@@ -21,22 +21,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -45,6 +42,8 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
@@ -63,6 +62,7 @@ public final class ExtensionCollector
for (ScmModule module : modules) {
collectRootElements(moduleClassLoader, module);
}
for (InstalledPlugin plugin : installedPlugins) {
collectRootElements(plugin.getClassLoader(), plugin.getDescriptor());
}
@@ -98,7 +98,7 @@ public final class ExtensionCollector
if (collection == null)
{
collection = Collections.EMPTY_SET;
collection = Collections.emptySet();
}
return collection;
@@ -123,7 +123,7 @@ public final class ExtensionCollector
}
else
{
exts = Collections.EMPTY_SET;
exts = Collections.emptySet();
}
return exts;
@@ -218,7 +218,7 @@ public final class ExtensionCollector
*
* @return
*/
public Set<WebElementDescriptor> getWebElements()
public Set<WebElementExtension> getWebElements()
{
return webElements;
}
@@ -272,6 +272,17 @@ public final class ExtensionCollector
return classes;
}
private Set<WebElementExtension> collectWebElementExtensions(ClassLoader defaultClassLoader, Iterable<WebElementDescriptor> descriptors) {
Set<WebElementExtension> webElementExtensions = new HashSet<>();
for (WebElementDescriptor descriptor : descriptors) {
if (isRequirementFulfilled(descriptor)) {
Class<?> loadedClass = loadExtension(defaultClassLoader, descriptor);
webElementExtensions.add(new WebElementExtension(loadedClass, descriptor));
}
}
return webElementExtensions;
}
private Class<?> loadExtension(ClassLoader classLoader, ClassElement extension) {
try {
return classLoader.loadClass(extension.getClazz());
@@ -307,13 +318,14 @@ public final class ExtensionCollector
restProviders.addAll(collectClasses(classLoader, module.getRestProviders()));
restResources.addAll(collectClasses(classLoader, module.getRestResources()));
Iterables.addAll(webElements, module.getWebElements());
webElements.addAll(collectWebElementExtensions(classLoader, module.getWebElements()));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final Set<WebElementDescriptor> webElements = Sets.newHashSet();
private final Set<WebElementExtension> webElements = Sets.newHashSet();
/** Field description */
private final Set<Class> restResources = Sets.newHashSet();