All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fluentlenium.core.components.LazyComponentList Maven / Gradle / Ivy

package org.fluentlenium.core.components;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.fluentlenium.core.domain.ListImpl;
import org.fluentlenium.core.domain.WrapsElements;
import org.openqa.selenium.WebElement;

/**
 * A list of component that lazy initialize from it's related list of elements.
 *
 * @param  type of component.
 */
public class LazyComponentList extends ListImpl implements List, WrapsElements, LazyComponents {
    private final ComponentInstantiator instantiator;
    private final Class componentClass;

    private final List elements;

    private final List> lazyComponentsListeners = new ArrayList<>();

    private final AtomicReference list = new AtomicReference<>();

    /**
     * Creates a new lazy component list.
     *
     * @param instantiator   component instantiator
     * @param componentClass component class
     * @param elements       underlying element list
     */
    public LazyComponentList(ComponentInstantiator instantiator, Class componentClass, List elements) {
        this.componentClass = componentClass;
        this.instantiator = instantiator;
        this.elements = elements;
    }

    public List getList() {
        Object value = this.list.get();
        if (value == null) {
            synchronized (this.list) {
                value = this.list.get();
                if (value == null) {
                    final List actualValue = transformList();
                    value = actualValue == null ? this.list : actualValue;
                    this.list.set(value);
                }
            }
        }
        return (List) (value == this.list ? null : value);
    }

    /**
     * Transform the actual list into components.
     *
     * @return transformed list
     */
    protected List transformList() {
        List components = new ArrayList<>();
        Map 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 componentMap) {
        for (LazyComponentsListener listener : lazyComponentsListeners) {
            listener.lazyComponentsInitialized(componentMap);
        }
    }

    @Override
    public boolean addLazyComponentsListener(LazyComponentsListener listener) {
        return lazyComponentsListeners.add(listener);
    }

    @Override
    public boolean removeLazyComponentsListener(LazyComponentsListener listener) {
        return lazyComponentsListeners.remove(listener);
    }

    @Override
    public boolean isLazy() {
        return true;
    }

    @Override
    public boolean isLazyInitialized() {
        return list == null;
    }

    @Override
    public List getWrappedElements() {
        return elements;
    }

    @Override
    public String toString() {
        return isLazyInitialized() ? getList().toString() : elements.toString();
    }

}