package org.fluentlenium.core.components;
import lombok.Getter;
import lombok.experimental.Delegate;
import org.fluentlenium.core.domain.WrapsElements;
import org.openqa.selenium.WebElement;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* A list of component that lazy initialize from it's related list of elements.
*
* @param <T> type of component.
*/
public class LazyComponentList<T> implements List<T>, WrapsElements, LazyComponents<T> {
private final ComponentInstantiator instantiator;
private final Class<T> componentClass;
private final List<WebElement> elements;
private final List<LazyComponentsListener<T>> lazyComponentsListeners = new ArrayList<>();
@Delegate
@Getter(lazy = true)
private final List<T> list = transformList();
/**
* Creates a new lazy component list.
*
* @param instantiator component instantiator
* @param componentClass component class
* @param elements underlying element list
*/
public LazyComponentList(ComponentInstantiator instantiator, Class<T> componentClass, List<WebElement> elements) {
this.componentClass = componentClass;
this.instantiator = instantiator;
this.elements = elements;
}
/**
* Transform the actual list into components.
*
* @return transformed list
*/
protected List<T> transformList() {
List<T> components = new ArrayList<>();
Map<WebElement, T> componentMap = new LinkedHashMap<>();
for (WebElement element : elements) {
T component = instantiator.newComponent(componentClass, element);
components.add(component);
componentMap.put(element, component);
}
fireLazyComponentsInitialized(componentMap);
return components;
}
/**
* First lazy components initialized event.
*
* @param componentMap components
*/
protected void fireLazyComponentsInitialized(Map<WebElement, T> componentMap) {
for (LazyComponentsListener<T> listener : lazyComponentsListeners) {
listener.lazyComponentsInitialized(componentMap);
}
}
@Override
public boolean addLazyComponentsListener(LazyComponentsListener<T> listener) {
return lazyComponentsListeners.add(listener);
}
@Override
public boolean removeLazyComponentsListener(LazyComponentsListener<T> listener) {
return lazyComponentsListeners.remove(listener);
}
@Override
public boolean isLazy() {
return true;
}
@Override
public boolean isLazyInitialized() {
return list == null;
}
@Override
public List<WebElement> getWrappedElements() {
return elements;
}
@Override
public String toString() {
return isLazyInitialized() ? list.toString() : elements.toString();
}
}