package org.fluentlenium.core.proxy;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.internal.WrapsElement;
import org.openqa.selenium.support.pagefactory.ElementLocator;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
/**
* Proxy handler for {@link WebElement}.
*/
public class ComponentHandler extends AbstractLocatorHandler<WebElement>
implements InvocationHandler, LocatorHandler<WebElement> {
private static final Method GET_WRAPPED_ELEMENT = getMethod(WrapsElement.class, "getWrappedElement");
/**
* Creates a new component handler
*
* @param locator element locator for this component
*/
public ComponentHandler(ElementLocator locator) {
super(locator);
if (this.locator instanceof WrapsElement) {
fireProxyElementSearch();
WebElement result = ((WrapsElement) this.locator).getWrappedElement();
if (result == null) {
throw noSuchElement();
}
this.result = result;
fireProxyElementFound(this.result);
}
}
@Override
public String getMessageContext() {
return "Element " + toString();
}
@Override
protected List<WebElement> resultToList(WebElement result) {
return Arrays.asList(result);
}
@Override
protected boolean isStale() {
try {
result.isEnabled();
return false;
} catch (StaleElementReferenceException e) {
return true;
}
}
@Override
public WebElement getElement() {
return result;
}
@Override
public WebElement getLocatorResultImpl() {
WebElement element;
try {
element = getHookLocator().findElement();
} catch (NoSuchElementException e) {
element = null;
}
if (element == null) {
throw noSuchElement();
}
return element;
}
@Override
public WebElement getInvocationTarget(Method method) {
if (method != null && method.getDeclaringClass().equals(Object.class)) {
return result;
}
if (getElement() == null) {
return null;
}
if (hooks != null && !hooks.isEmpty()) {
return hooks.get(hooks.size() - 1);
}
return getElement();
}
//CHECKSTYLE.OFF: IllegalThrows
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (GET_WRAPPED_ELEMENT.equals(method)) {
return loaded() ? getLocatorResult() : proxy;
}
return super.invoke(proxy, method, args);
}
//CHECKSTYLE.ON: IllegalThrows
}