package org.fluentlenium.core.hook; import org.fluentlenium.core.FluentControl; import org.fluentlenium.core.components.ComponentInstantiator; import org.fluentlenium.utils.ReflectionUtils; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.pagefactory.ElementLocator; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; /** * Builder of hook chains from element supplier, element locator supplier and hook definitions list. */ public class DefaultHookChainBuilder implements HookChainBuilder { private final FluentControl control; private final ComponentInstantiator instantiator; /** * Creates a new default hook chain builder * * @param control control interface * @param instantiator component instantiator */ public DefaultHookChainBuilder(FluentControl control, ComponentInstantiator instantiator) { this.control = control; this.instantiator = instantiator; } @Override public List<FluentHook> build(Supplier<WebElement> elementSupplier, Supplier<ElementLocator> locator, Supplier<String> toStringSupplier, List<HookDefinition<?>> hooks) { List<FluentHook> chain = new ArrayList<>(); Supplier<WebElement> currentSupplier = elementSupplier; for (HookDefinition<?> hook : hooks) { FluentHook<?> newObject; try { newObject = newInstance(hook.getHookClass(), control, instantiator, currentSupplier, locator, toStringSupplier, hook.getOptions()); } catch (NoSuchMethodException e) { throw new HookException(e); } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) { throw new HookException(e); } FluentHook<?> hookInstance = newObject; currentSupplier = () -> hookInstance; chain.add(hookInstance); } return chain; } /** * Creates a new hook instance. * * @param hookClass hook class * @param fluentControl control interface * @param instantiator component instantiator * @param elementSupplier element supplier * @param locatorSupplier element locator supplier * @param toStringSupplier element toString supplier * @param options hook options * @return new hook instance * @throws NoSuchMethodException if a matching method is not found. * @throws IllegalAccessException if this {@code Constructor} object * is enforcing Java language access control and the underlying * constructor is inaccessible. * @throws InstantiationException if the class that declares the * underlying constructor represents an abstract class. * @throws InvocationTargetException if the underlying constructor * throws an exception. */ protected FluentHook<?> newInstance(Class<? extends FluentHook<?>> hookClass, FluentControl fluentControl, ComponentInstantiator instantiator, Supplier<WebElement> elementSupplier, Supplier<ElementLocator> locatorSupplier, Supplier<String> toStringSupplier, Object options) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { return ReflectionUtils .newInstance(hookClass, fluentControl, instantiator, elementSupplier, locatorSupplier, toStringSupplier, options); } }